「overflow: hidden」が予期しない挙動を起こす理由|意外と複雑なCSS仕様を解く
こんにちは!
今日は「overflow: hiddenが予期しない挙動を起こす理由」について、実践的に解説していきます。
overflowプロパティがめっちゃ複雑な理由
僕も最初はoverflow: hiddenを単純に「はみ出したコンテンツを隠すプロパティ」だと思ってました。
でもね、現場で働くようになるとそれだけじゃ説明できない挙動に何度も出くわすんですよ。
実はoverflow: hiddenには3つの役割があるんです:
- はみ出したコンテンツを隠す(基本機能)
- 新しいブロックフォーマッティングコンテキスト(BFC)を作成する(副作用)
marginの相殺(マージンコラプス)を防ぐ
特に後の2つが原因で、想定外の動きが生じることがほんまにめっちゃ多いんです。
単にコンテンツを隠すためだけに使ったはずなのに、レイアウトが変わっちゃった…って経験ないですか?
BFC(ブロックフォーマッティングコンテキスト)を理解する
BFCというのは、ブラウザがブロック要素をどう配置するかのルールセットのことです。overflow: hiddenを指定すると、その要素が「新しいBFC」を確立するんですよ。
新しいBFCが確立されると、以下のような変化が起こります:
- その要素の内側のフロートされた要素が、外側のレイアウトに影響しなくなる
- フロート要素が隣のブロック要素と重なるのが防がれる
- 垂直方向の
marginの相殺(マージンコラプス)が起こらなくなる
つまり、あなたが「崩れたレイアウトを修正したい」って気持ちでoverflow: hiddenを入れると、その副作用で別の場所のマージンが効かなくなったり、レイアウトが変わったりするんですよ。
例えば、親要素にoverflow: hiddenを指定すると、内側の子要素のトップのmarginが親要素に相殺されなくなります。
これが原因で「あれ?このマージンが効かないぞ」という現象が起こるわけです。
よくある失敗例と対処法3つ
失敗例1:フロート対策として使ったら、マージンが変わった
昔の案件で、左側にフロートされた画像があって、その下のテキストが画像の下に回り込まないようにするために、テキスト要素にoverflow: hiddenを指定しました。
確かに回り込みは止まったんですが、テキストのトップmarginの効きが変わってしまったんです。
このケースでの対処法は、overflow: hiddenじゃなく、別の方法を使うことです:
- 方法1:
display: flow-rootを使う(推奨)
これも新しいBFCを作成しますが、overflow: hiddenほど副作用がありません。 - 方法2:
display: flexやdisplay: gridを使う
レイアウトを変更できるなら、こちらの方がモダンでコントロールしやすいです。 - 方法3:フロートじゃなくflexboxを使う
そもそもの設計を変えるのが最善です。
失敗例2:高さが自動計算されなくなった
親要素にoverflow: hiddenを指定したら、その親の高さが思わぬ値になってしまったことがあります。
原因は、内側のフロート要素の高さが計算に含まれなくなったためです。
フロート要素は通常、親要素の高さ計算に含まれません。
昔は親要素にoverflow: hiddenやoverflow: autoを指定して、「フロートの高さを含める」という技(clearfix的な使い方)をしていました。
でも今はdisplay: flow-rootの方が明確です。
失敗例3:意図しないスタイルが当たってた
これはほんま厄介やったんですが、親要素にoverflow: hiddenを指定することで、CSSのセレクタの優先度ルールが予想外に働くことがあります。
直接的ではないですが、BFCの確立によって、:not()や子孫セレクタの効きが変わることがあるんですよ。
対処としては、overflow: hiddenを使う前に「本当にこれが必要か」を自問することが大事です。
多くの場合、display: flexやdisplay: gridで解決する方が、よりコントロールしやすいです。
まとめ
overflow: hiddenは便利なプロパティですが、副作用をちゃんと理解した上で使わないと、あちこちでトラブルが発生します。
特に覚えておくといいのは:
overflow: hiddenは単なる「隠す」機能ではなく、BFCを確立する副作用がある- マージンの相殺やフロート計算に影響を与える
- フロート対策には
display: flow-rootの方が副作用が少ない - 新しいレイアウト方法(flexbox、grid)で最初から設計するのが最善
現場では「とりあえずoverflow: hidden入れとけば大丈夫」みたいなノリで使われることもありますが、デバッグのときにめっちゃ困ることになります。
プロパティ一つ一つの理由を理解して使うクセをつけると、後々のトラブルが減りますよ。
Web制作で困ったことがあったら、またこのブログを覗いてくださいね!
― クリオ