float
floatプロパティを使用することで、float(浮く)という名前の通り、要素を浮き上がらせ、回り込ませることができます。また、floatを使用した後には「floatを解除する」という操作が必要になります。
float:left
を指定すると左に回り込み、float:right
を指定すると右に回り込みます。floatを使用したあとには、親要素に対してclear fixと呼ばれるfloatを解除するためのクラスを指定します。
HTML
<div class="clearfix">
<div class="sample_a">左回り込み</div>
<div class="sample_b">右回り込み</div>
</div>
CSS
.clearfix:after {
content: "";
display: block;
clear: both;
}
.sample_a {
float: left;
}
.sample_b {
float: left;
}
.clearfix:after {...}
がclear fixです。floatを設定した要素を囲む親要素に対して、class="clearfix"
を指定して、floatを解除します。clearプロパティは、直前に設定したfloatを打ち消す効果を持っています。疑似要素の:after
によって、親要素の要素の直後にclear:both
を持った空の要素を仕込んでいるというわけです。
float(浮く)の意味
「要素を回り込ませる」と説明されることが多いfloatですが、本来の意味は「浮く」です。floatは、新聞紙の上に配置された画像のように、文字が画像に被らないように避けて配置するような使い方を想定して導入されました。そのため、divタグなどのブロックレベル要素は必ず前後に改行が入りますが、floatプロパティが設定された要素は浮いている状態になり、本来のブロックレベル要素の配置ルールから外れます。この仕様を理解するために次の例を見てください。
mainとsideという2つのブロックレベル要素をfloatで回り込ませる場合を考えてみます。ブラウザで表示すると、初期状態では以下のようなコードと見た目になります。
HTML
<div id="contents">
<div id="main">メイン</div>
<div id="side">サイド</div>
</div>
CSS
#contents {
width: 700px;
margin:0 auto;
background: #CCCCCC;
}
#main {
width: 300px;
height: 300px;
background: #333DFF;
}
#side {
width: 300px;
height: 300px;
background: #27C42A;
}
ここでmainにfloat: left
を追加すると以下のようになります。
CSS
#contents {
width: 700px;
margin: 0 auto;
background: #CCCCCC;
}
#main {
width: 300px;
height: 300px;
background: #333DFF;
float: left;
}
#side {
width: 300px;
height: 300px;
background: #27C42A;
}
sideの要素が画面から消えて、「サイド」という文字列だけがmainの下に表示されています。どういうメカニズムでこのような表示になるのかというと、mainにfloat: left
を指定したことでmainが浮き上がった状態になり、その下に重なるようにsideの要素が流れ込んでしまっています。今は見えませんが、青いブロックの下に重なるように緑のブロックが存在しているということです。
存在はしていてもスペースが無いので「サイド」という文字列は行き場を無くしてしまい、このような位置に退避しているのです。
続いて、sideにもfloat: left
を指定してみると、以下のようになります。
CSS
#contents {
width: 700px;
margin: 0 auto;
background: #CCCCCC;
}
#main {
width: 300px;
height: 300px;
background: #333DFF;
float: left;
}
#side {
width: 300px;
height: 300px;
background: #27C42A;
float: left;
}
mainに重なるようにして隠れていたsideが見えるようになりました。しかし、ここで注目してほしいのは親要素のcontentsという灰色のブロックが見えなくなってしまったことです。これはcontentsには高さ(height)が指定されておらず、子要素(main, side)のheightに依存していることが原因です。contentsは、mainとsideが浮動状態になったことでmainとsideを認識することができなくなってしまったので、表示上は見えなくなってしまったということです。contentsを再び表示するにはcontentsに対してheightを指定する必要があります。
また、余談になりますが、今回はブロックレベル要素に対してfloatを適用しましたが、果たしてインライン要素にfloatを適用した場合はどうなるのでしょうか?
インライン要素にfloatを適用した場合、インライン要素は暗黙的にブロックレベル要素に変換されます。つまり、「display:block;」といちいち書かなくとも、floatが勝手にブロックレベル要素に変換してくれます。
流れ込みでの配置を覚える
今回はfloatプロパティを扱います。floatの最大の特徴は、回り込んでいる連続した複数の要素がある場合、要素の合計の幅が親要素の幅に収まりきらない場合は、次の行に流れ込むという仕様です。
例えば、8つのブロック(要素)を4行2列にして並べたい場合、子要素の幅を20%、左右のmarginを2.5%にすれば、要素を4つ並べると100%になり、5つ目の要素が幅に収まりきらず自動的に2列目に流れ込むので、4行2列のレイアウトを実現することができます。
4行2列のレイアウトを作るときの記述例
HTML
<ul class="sample_a cf">
<li class="sample_b"></li>
<li class="sample_b"></li>
<li class="sample_b"></li>
<li class="sample_b"></li>
<li class="sample_b"></li>
<li class="sample_b"></li>
<li class="sample_b"></li>
</ul>
CSS
.cf:after {
content: "";
display: block;
clear: both;
}
.sample_a {
width: 500px;
height: 220px;
list-style-type: none;
}
.sample_b {
float: left;
width: 20%;
height: 100px;
margin: 5px 2.5%;
background-color: #000;
}
動作例
まとめ
最近はfloatによる配置よりもflexboxによる配置を行うことが多くなってきたので、floatは本来の使い方である「新聞の画像配置」のような使い方に限られてくるのかなぁと思います。
flexboxでfloatのような配置をしたい場合は、display: flex;
とflex-wrap: wrap;
だけで今回のような流れ込み配置ができてしまうので、こちらのほうが圧倒的に楽です。