CSSのfloatとは?回り込み・clearfix・Flexboxの使い分けを解説

コードが書かれたモニター

CSSを学び始めて少し経つと、必ずと言っていいほど出てくるのがfloatというプロパティです。私もWeb制作を始めたばかりの頃、画像の横に文章をきれいに回り込ませたくて、おそるおそるfloat: left;と書いてみた記憶があります。あの「うまくいった!」という小さな感動は、今でもなんとなく覚えているんですよね。

ところが、このfloatがなかなかのクセ者でして。横並びのレイアウトを作ろうとした途端、親要素の高さが消えたり、次の要素が変な位置に食い込んできたり。初心者が最初につまずく定番ポイントだったりします。私も当時は「なんで崩れるの…」と画面とにらめっこしていました。

さらにややこしいのが、ここ数年でfloatの立ち位置がガラッと変わったことです。今はページ全体のレイアウトにはFlexboxやCSS Gridを使うのが主流で、floatは本来の「文章の回り込み」という役割に戻っています。つまり、昔の解説をそのまま鵜呑みにすると、わざわざ古いやり方で苦労してしまうことになりかねません。

そこでこの記事では、floatの基本と回り込みの仕組みから、回り込みを解除するclear、高さが潰れる問題とclearfix、そして「今ならどう書くか」というFlexbox・Gridとの使い分けまでを、初心者の方向けにかみ砕いて整理していきます。読み終わるころには、floatに出会っても慌てず、「ここはfloatでいい」「ここはFlexboxだな」と判断できるようになっているはずです。古いサイトの保守でfloatに出くわす機会はまだまだあるので、仕組みを押さえておくと地味に効いてきますよ。

floatとは?まずは基本から

floatは、要素を左または右に寄せて、その周囲にテキストやインライン要素を回り込ませるCSSプロパティです。一番イメージしやすいのは、雑誌や新聞のように、画像の横に文章が流れ込んでいくレイアウトですね。

たとえば、画像を左に寄せて、その右側に文章を回り込ませたいときは次のように書きます。

.image {
  float: left;
  margin-right: 20px;
}

HTMLはこんな感じです。

<img src="sample.jpg" alt="" class="image">
<p>ここに文章が入ります。画像の右側にテキストが回り込みます。</p>

これだけで、画像の右側に文章がスッと回り込んでくれます。floatは本来、こうして画像などの周囲に文章を流し込むために生まれたプロパティなんですね。この使い方こそがfloatの王道、と覚えておいてください。

参考リンク:MDN Web Docs:float

関連記事:【CSS】floatさせた画像の下にテキストを回り込ませない方法(サンプルコードあり)

floatの値は5つ

floatに指定できる値は、次の5つです。日常的に使うのはほぼleftrightですが、ひと通り知っておくと安心です。

  • left:要素を左に寄せる
  • right:要素を右に寄せる
  • none:回り込みを行わない(初期値)
  • inline-start:文章の開始方向へ寄せる
  • inline-end:文章の終了方向へ寄せる

inline-startinline-endは、文字の流れる向き(書字方向)に合わせて寄せ先が変わる比較的新しい値です。たとえば右から左に読むアラビア語のページでは、inline-startが右側になります。日本語の一般的なサイトでは、まずleftrightを見かけると思っておけば大丈夫です。

float: left; と float: right; の例

左寄せはfloat: left;、右寄せはfloat: right;です。回り込む文章との間に余白がないと窮屈に見えるので、marginもセットで指定するのがコツです。

.float-left {
  float: left;
  margin: 0 20px 20px 0;
}

.float-right {
  float: right;
  margin: 0 0 20px 20px;
}

左寄せなら右と下に、右寄せなら左と下に余白を作ると、文章との間に程よいすき間ができて読みやすくなります。プロフィール画像の横に説明文を置く、といった場面で今でも普通に使える書き方です。

floatで必ずぶつかる「高さが潰れる」問題

さて、ここからがfloatの落とし穴です。初心者が最初に「えっ、なんで?」となるのが、floatした子要素を持つ親要素の高さが、ゼロになったように潰れてしまう問題です。

たとえば、こんなHTMLとCSSがあるとします。

<div class="box">
  <div class="item">左</div>
  <div class="item">右</div>
</div>
.item {
  float: left;
  width: 50%;
}

子要素の.itemがどちらもfloatしていると、親の.boxは子の高さを認識できず、まるで中身が空っぽのように高さが潰れてしまいます。その結果、後ろに続く要素が上に食い込んできて、レイアウトがガタッと崩れる、というわけです。これはfloatの仕様によるもので、バグではありません。だからこそ、次に説明する「回り込みの解除」がセットで必要になります。

関連記事:【簡単解説】floatで横並びにしたリストをCSSで中央揃えする方法

回り込みを解除する clear

floatの回り込みを止めたいときに使うのがclearです。

.clear {
  clear: both;
}

clear: left;で左の回り込みを、rightで右を、bothで両方を解除します。昔は、floatした要素の後ろに解除専用の空要素を置く方法がよく使われていました。

<div class="box">
  <div class="item">左</div>
  <div class="item">右</div>
  <div class="clear"></div>
</div>

ただ、この方法は装飾のためだけの空要素がHTMLに増えてしまうので、今はあまりおすすめしません。意味のないタグが増えると、後で見返したときに「これ何だっけ?」となりがちです。clearの考え方自体は大事なので、仕組みとして理解しておきましょう。

clearfixと、今どきの display: flow-root

空要素を増やさずに親要素へfloatを含ませる定番テクニックが、おなじみのclearfixです。親要素に::after疑似要素を仕込んで、見えない要素でclearをかける仕組みですね。

.clearfix::after {
  content: "";
  display: block;
  clear: both;
}
<div class="box clearfix">
  <div class="item">左</div>
  <div class="item">右</div>
</div>

これで親要素が子の高さを含むようになり、潰れ問題が解決します。古いサイトの保守をしていると、このclearfixは本当によく出てくるので、見た瞬間に「ああ、float対策ね」と分かるようにしておくと楽です。

ただ、新しく書くなら、もっとスッキリした方法があります。それがdisplay: flow-root;です。

.box {
  display: flow-root;
}

MDNでも、flow-rootは「まさにこの問題を解決するためだけに用意された値で、ハックのような副作用がない」と紹介されています。親要素にこれを一行足すだけで、疑似要素のおまじないなしにfloatを含められるんです。clearfixの代わりに、まずこちらを検討してみてください。

ちなみに、昔はoverflow: hidden;で代用する方法もありましたが、これははみ出した要素が切れてしまうことがあり、ドロップダウンメニューや影が消える原因になります。本来は別目的のプロパティなので、float解除のために安易に使うのは避けたほうが無難です。

参考リンク:MDN Web Docs:浮動(Floats)

レイアウトは今やFlexboxとGridが主流

ここが今回いちばん伝えたいところです。横並びや複数カラムのレイアウトは、もうfloatで頑張る時代ではありません。MDNでも、floatは「Flexboxとグリッドの登場で、本来の役割(文章の回り込み)に戻った」とはっきり書かれています。

昔はこんなふうにfloatで2カラムを組んでいました。

.content {
  float: left;
  width: 70%;
}

.sidebar {
  float: right;
  width: 28%;
}

.wrapper {
  display: flow-root;
}

同じ2カラムを、今ならFlexboxでこう書けます。

.wrapper {
  display: flex;
  gap: 24px;
}

.content {
  flex: 1;
}

.sidebar {
  width: 300px;
}

clearfixも幅の細かい調整も要らず、要素間のすき間はgapで一発。floatより直感的で、高さが潰れる悩みからも解放されます。さらに、カードを格子状に並べるような二次元のレイアウトなら、CSS Gridの出番です。

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

Flexboxは「行か列か」の一次元、Gridは「行と列」の二次元、とざっくり覚えておくと使い分けやすいです。新規制作では、まずこの2つで考えるのが今の基本だと思ってください。

参考リンク:MDN Web Docs:フレックスボックス

関連記事:グリッドデザインとは?初心者にもわかるWeb制作の整列と余白の基本&CSS Grid入門

用途ごとの使い分け早見表

迷ったときの目安として、ざっくり整理しておきます。

  • 画像に文章を回り込ませる → float
  • 横並びメニュー → Flexbox
  • 2カラムレイアウト → Flexbox(または Grid)
  • カード一覧・格子状の配置 → Grid
  • 古いサイトの修正 → 既存のfloatに合わせて部分対応

要するに、文章の回り込みはfloat、それ以外のレイアウトはFlexboxかGrid。この線引きを持っておけば、たいていの場面で迷わなくなります。

floatで崩れたときの確認ポイント

既存サイトの修正などでfloatのレイアウトが崩れたら、次の点を上から順に見ていくと原因にたどり着きやすいです。

  • 親要素にclearfixやdisplay: flow-root;が入っているか
  • floatした要素の合計幅が100%を超えていないか
  • box-sizing: border-box;が指定され、paddingやborderを含めた幅になっているか
  • 次の要素に回り込みが影響していないか(必要ならclear
  • スマホ表示でfloatを解除できているか

特に見落としやすいのが幅の計算です。box-sizing: border-box;が無いと、paddingやborderの分だけ要素が太って合計幅が100%を超え、カクッと折り返してしまいます。また、スマホでは横並びをやめて縦並びにすることが多いので、メディアクエリでfloatを解除します。

@media screen and (max-width: 768px) {
  .content,
  .sidebar {
    float: none;
    width: 100%;
  }
}

PCでは横並び、スマホでは縦並び、という切り替えはfloatレイアウトの定番対応です。とはいえ、こうした手間を考えると、やはり新規ならFlexboxのほうが断然ラクだと実感できるはずです。

まとめ:回り込みはfloat、レイアウトはFlexbox

長くなりましたが、最後にぎゅっとまとめます。floatは「要素を左右に寄せて文章を回り込ませる」ためのプロパティで、今はその本来の役割に戻っています。かつてレイアウトの主役だった時代は終わり、横並びや複数カラムはFlexboxとCSS Gridに主役が移りました。

覚えておきたいポイントは、次のとおりです。

  • float: left;で左寄せ、float: right;で右寄せ
  • floatした子要素は親の高さに含まれず、潰れることがある
  • 解除はclear、親に含めるなら今はdisplay: flow-root;が手軽
  • clearfixは古いサイトで頻出。仕組みを知っておくと保守がラク
  • 新規レイアウトはFlexboxかGridで考える

floatは「古くて使えない技術」ではなく、「用途が限定された、今も現役のプロパティ」と捉えると、すっきり整理できると思います。文章の回り込みにはfloat、レイアウト全体にはFlexboxやGrid。この使い分けが身につくと、新規制作はもちろん、古いCSSを読み解くときの見通しもぐっと良くなります。

もし今、floatで組まれた古いレイアウトの保守に手こずっているなら、思い切ってFlexboxに置き換えてみるのも一つの手です。書き換えてみると、コードがどれだけシンプルになるかにきっと驚くはずですよ。