CSSで要素をfloatさせてレイアウトした時、後続要素のfloatを解除する方法として、clearfix hackのほかに、float要素の親要素にoverflow: hidden
を指定することにより、floatで潰れてしまった高さを認識させる方法があります。この方法はclearfixに比べCSSへの記述が簡単なので初心者にはとっつきやすいですが、ページのデザインによっては使いどころに注意が必要です。
たとえばこの現象(下図)。これは、高さが異なる2つのdiv要素をそれぞれfloat: left
, float: right
で配置したものです。floatしたdivのサイズと表示位置をブラウザ画面上で確認するため、CSSにoutline: 1px solid red;
を指定して要素の矩形領域を表示させたつもりが、ヘンテコな表示になってしまいました。
<div class="container">
<div class="left">Lorem ipsum dolor sit amet.</div>
<div class="right">Lorem ipsum dolor sit amet.</div>
</div>
CSSの内容
.container {
width: 700px;
margin: 50px auto 0;
overflow: hidden;
}
.left {
float: left;
width: 300px;
height: 200px;
margin-left: 20px;
outline: 1px solid red;
}
.right {
float: right;
width: 300px;
height: 100px;
outline: 1px solid red;
}
なぜこんな表示の欠けが生じるのでしょう? 輪郭線outlineプロパティに関するMDNの解説を読んでやっと原因がわかりました。
輪郭線は以下の点で境界線とは異なります。
輪郭線は領域を占有せず、要素のコンテンツの外側に描かれます。
CSSの仕様でいうと該当箇所はこれか。4.5. Offsetting the Outline: the outline-offset property
By default, the outline is drawn starting just outside the border edge.
つまり、要素のborder含んだ領域の外側に輪郭線(outline)が描画されるため、親要素のoverflow: hidden
によって輪郭線が切り取られてしまったわけですね。上のスクリーンショットで、左側にfloatしたブロック要素については左辺のoutlineが欠けずに表示できていますが、実はdiv.left
にmargin-left: 20px;
を設定していたからです。
ちなみに、上に述べたoutline-offsetプロパティを使って、outline-offset: -1px;
を追加すれば、輪郭線を矩形の内側方向(borderの位置)に表示させることができます。
もっとありがちな例だと、box-shadow
で影を付けたブロック要素を横並びにfloatで配置した時、右端のブロックだけ影がクリッピングされてしまうことがあります。この現象も、borderの外側に広がった影が、float解除のoverflowプロパティによって切り取られたのが原因です。
float要素の表示欠けが生じるコード例
上に紹介したものに加え、oveflow: hidden
によるfloat解除でfloat要素の「表示欠け」を起こす可能性のあるプロパティの使い方とそのサンプルコードを下記Penに書きました。
See the Pen [CSS basics] Clearing floats with overflow:hidden or clearfix by Kazuhiro Hashimoto (@kaz_hashimoto) on CodePen.
このPenは、6種類のプロパティについて、float解除をそれぞれ「`overflow: hidden`で実施した場合」「clearfixで実施した場合」の計12個のサンプルを表示します。各サンプルの構成は以下のとおりです。- 背景黒の長方形: 親要素div.container
- 白い枠線の長方形: float要素div.left, div.right