web-dev-qa-db-ja.com

位置が固定された親と子、親のオーバーフロー:隠れたバグ

問題があるかどうかはわかりませんが、なぜoverflow:hiddenは、fixedの親/子要素では機能しません。

以下に例を示します。

CSSおよびHTML:

.parent{
  position:fixed;
  overflow:hidden;
  width:300px;
  height:300px;
  background:#555;
}
.children{
  position:fixed;
  top:200px;
  left:200px;
  width:150px;
  height:150px;
  background:#333;
}
<div class="parent">
  <div class="children">
  </div>
</div>

ライブデモ: jsFiddle

49
kirkas

固定位置要素は、別の要素ではなく、ビューポートに対して固定されているためです。したがって、ビューポートは切り取らないため、オーバーフローは無関係になります。

Position:absoluteの要素の位置と寸法は、その包含ブロックに対して相対的ですが、position:fixedの要素の位置と寸法は、常に最初の包含ブロックに対して相対的です。これは通常、ビューポートです:ブラウザウィンドウまたはペーパーのページボックス。

参照: http://www.w3.org/wiki/CSS_absolute_and_fixed_positioning#Fixed_positioning

43
j08691

CSS clip: rect(top, right, bottom, left);を使用して、固定された要素を親にクリップすることを検討できます。 http://jsfiddle.net/lmeurs/jf3t0fmf/ のデモを参照してください。

注意してください!

クリップスタイルは広くサポートされていますが、主な欠点は次のとおりです。

  1. 親の位置を静的または相対位置にすることはできません(相対位置のコンテナー内で絶対位置の親を使用できます)。
  2. autoの値は_100%_に等しいものの、rect座標はパーセンテージをサポートしていません。 clip: rect(auto, auto, auto, auto);;
  3. 少なくともIE11とChrome34では、子要素を持つ可能性が制限されています。子要素の位置を相対または絶対に設定したり、スケールのようなCSS3変換を使用したりすることはできません。

詳細については、 http://tympanus.net/codrops/2013/01/16/understanding-the-css-clip-property/ を参照してください。

編集:Chromeは、 backface-visibility を適用するときに、子要素の配置とCSS3変換をより適切に処理するようです。

_-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
_

メインの子要素に。

また、古いブラウザやモバイルブラウザでは完全にサポートされていないか、多少手間がかかる場合があることに注意してください。 bellafuchsia.com のメニューの実装を参照してください。

  1. IE8はメニューを適切に表示しますが、メニューリンクはクリックできません。
  2. IE9は、スクロールせずにメニューを表示しません。
  3. iOS Safari <5はメニューをうまく表示しません。
  4. iOS Safari 5+は、スクロール後にクリップされたコンテンツをスクロールで再描画します。
  5. FF(少なくとも13 +)、IE10 +、ChromeおよびChrome for Androidはナイスをプレイしているようです。

編集2014-11-02:デモURLが更新されました。

79
lmeurs

2016アップデート:

Coderwall で見られるように、新しいスタッキングコンテキストを作成できます。

<div style="transform: translate3d(0,0,0);overflow:hidden">
   <img style="position:fixed; ..." />
</div>

http://dev.w3.org/csswg/css-transforms/#transform-rendering

CSSボックスモデルによってレイアウトが制御される要素の場合、変換のnone以外の値は、スタックコンテキストと包含ブロックの両方を作成します。オブジェクトは、固定配置された子孫の包含ブロックとして機能します。

24
Hugo H

クリップを使用する代わりに、親要素で{border-radius: 0.0001px}を使用することもできます。これは、絶対/固定配置要素のみで機能しません。

8
ZhenyaUsenko

固定位置要素のオーバーフローを非表示にする場合、私が見つけた最も簡単なアプローチは、要素をコンテナ要素内に配置し、含まれている要素の代わりにその要素にposition:fixedおよびoverflow:hiddenを適用することです(これが機能するには、含まれている要素からposition:fixedを削除する必要があります)。固定コンテナのコンテンツは、期待どおりにクリップされるはずです。

私の場合、固定位置要素で object-fit:cover を使用することに問題がありました(overflow:hiddenに関係なく、ページ本体の境界外に流出していました)。 overflow:hiddenを使用して固定コンテナ内に配置すると、問題が修正されました。

3
Nick F

右側の列の幅が固定され、左側の列の幅が柔軟であるという、流動的なレイアウトに関する同様の非常に複雑な問題がありました。固定コンテナは、フレキシブルコラムと同じ幅にする必要があります。私の解決策は次のとおりです。

[〜#〜] html [〜#〜]

<div id="wrapper">
    <div id="col1">
    <div id="fixed-outer">
        <div id="fixed-inner">inner</div>
    </div>
    COL1<br />Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
    </div>
    <div id="col2">COL2</div>
</div>

[〜#〜] css [〜#〜]

    #wrapper {
    padding-left: 20px;
}

#col1 {
    background-color: grey;
    float: left;
    margin-right: -200px; /* #col2 width */
    width: 100%;
}

#col2 {
    background-color: #ddd;
    float: left;
    height: 400px;
    width: 200px;
}

#fixed-outer {
    background: yellow;
    border-right: 2px solid red;
    height: 30px;
    margin-left: -420px; /* 2x #col2 width + #wrapper padding-left */
    overflow: hidden;
    padding-right: 200px; /* #col2 width */
    position: fixed;
    width: 100%;
}

#fixed-inner {
    background: orange;
    border-left: 2px solid blue;
    border-top: 2px solid blue;
    height: 30px;
    margin-left: 420px; /* 2x #col2 width + #wrapper padding-left */
    position: absolute;
    width: 100%;
}

ライブデモhttp://jsfiddle.net/hWCub/

0