【CSS】いまさらだけどclearfixを知ったので図解します！

## はじめに

今回はCSSでレイアウト崩れを防止できる、**clearfix**という手法をご紹介します！
この方法自体は2004年からあるらしく全然定番のお話らしいですが、自分は本を読んでて最近やっと仕組みがハラオチしたので、ぜひアウトプットさせていただきたく参上しました！

## clearfixいつ使うの？：floatプロパティでレイアウト崩れちゃう！という場合

基本的にHTMLって縦方向に骨組みを作成するじゃないですか。

![スクリーンショット 2020-12-05 21.23.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469936/cddb3f23-0526-b6e1-a065-69d8c9b027a4.png)

これは夏目漱石のポートフォリオサイト「Kusa-Makura」（さっき作った）ですが、HTMLとしては以下のようになっています。（ボディー部のみ）

```html

      <div class="main">
        <h1>About</h1>
        <section class="profile">
          <div class="profile-text">
            <h2 class="icon">Profile</h2>
            <p><span>夏目漱石</span><br>
              わし。なんかとてもすごい人。<br>
              すごすぎて顔が1000円札に使われていたこともある。<br>しかし今その辺でわしの1000円札を使おうとすると、店員にちょっと変な顔されると思うので注意されたい。<br>ここからWikipedia・・・本名は夏目 金之助（なつめ きんのすけ）。俳号は愚陀仏。明治末期から大正初期にかけて活躍した近代日本文学の頂点に立つ作家の一人である。代表作は『吾輩は猫である』『坊っちゃん』『三四郎』『それから』『こゝろ』『明暗』など。明治の文豪として日本の千円紙幣の肖像にもなり、講演録「私の個人主義」も知られている。漱石の私邸に門下生が集った会は木曜会と呼ばれた。・・・ここまでWikipedia</p>
          </div>
          <img src="images/natsume.jpg" alt="夏目漱石のプロフィール画像" class="profile-image" width="200">
        </section>
        <section class="career">
            <h2 class="icon">Works</h2>
              <p><span>草枕</span><br>
              山路を登りながら、こう考えた。<br>
              智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。とかくに人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟った時、詩が生れて、画が出来る。</p>
        </section>
      </div>
```

で、HTMLだととにかく縦方向にしか進まないので、横方向にレイアウトしたいときに便利なのがCSSのfloatプロパティです。

![スクリーンショット 2020-12-05 21.39.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469936/737adf2c-8cd1-18c0-8ab3-5935bc918348.png)

上の画像のように、プロフィール内のテキスト部分を左に、画像を右に寄せていい感じのレイアウトにしたかったのですが…
自分が最初に辿り着いたのは、以下のような状態でした。

![スクリーンショット 2020-12-05 21.42.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469936/b91dbe26-5620-f8ef-b96c-a4cb10f77daf.png)

ヘッダー部分はうまいこと左右がいい感じになったのですが、ボディー部分のレイアウトが崩れてしまったのです……
こういう場合に、clearfixが役立ちます！

## そもそもなぜfloatはレイアウト崩れるの？：親要素の高さがなくなるから

floatでレイアウトが崩れるのは、親要素の高さがなくなるからです。
（ヘッダーは親要素の高さをあらかじめ決めていますが、ボディー部は高さを決めておくことってなかなかないですよね）
もともと親要素は、内包する子要素に合わせて高さを変えられます。

![advCal01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469936/544a6afc-5dcc-944a-7ad6-9cec1c7fdfa3.png)

しかしfloatプロパティを適用すると、文字通り親から子が**浮いて**しまいます。

![advCal02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469936/1b4bbca3-ea6b-87d1-8acc-baeb652554d7.png)

今回のようなレイアウトだと、プロフィールセクション内は左のプロフィール文と右の写真しか子要素を持たないため、両方浮かせてしまうと、親要素は高さゼロになってしまいます。

![advCal03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469936/6bcce652-dce3-e9e5-e651-88acba501add.png)

そして、floatは後続の要素を回り込ませる特性があるため、左の文と右の写真の段差に次のレイアウト要素が回り込んでしまっているというわけです。

## clearfixどう使うの？：親要素にclearfixで杭を打ち込んで高さを維持する！

さて、ここでいよいよclearfixの登場です！やり方を順を追って説明します。

### ①HTMLで親要素にclearfixクラスを追加する
```html
      <div class="main">
        <h1>About</h1>
        <section class="profile clearfix"> <!--  ここ！  -->
          <div class="profile-text">
            <h2 class="icon">Profile</h2>
            <p><span>夏目漱石</span><br>
              わし。なんかとてもすごい人。<br>
<!--  後略  -->
```

### ②CSSでclearfixに空のボックスを生成する
```css

.clearfix:after {
  content: "";
}
```

これは何をしているかというと、擬似要素「:after」を利用して、親要素の末尾に空のボックスを置いています。
まだ回り込みは解消されていません。

![advCal04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469936/56816013-d524-5b8d-aa34-5cd25787a45f.png)

### ③空のボックスをブロックレベル要素にする
```css
.clearfix:after {
  content: "";
  display: block;
}
```

`display: block;`を追加して空のボックスをブロックレベル要素にしています。
ブロックレベル要素にすると必ず前後に改行が入り、高さや幅の指定が可能になります。（↔️インライン要素：テキストの一部として扱われるため、改行は入りません）
つまり、前後の要素の回り込みが解消されます。

![advCal05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469936/b8d708c5-a17a-76f9-5ffd-bb29cd0c5a13.png)

### ④空のボックスのfloatを解除する
```css
.clearfix:after {
  content: "";
  display: block;
  clear: both;
}
```

最後にclearプロパティを使って、空のボックスにも自動的に適用されていたfloatを解除します。
これにより、空のボックスが杭を打ち込むような形になり、親要素の高さを保てるようになります！

![advCal06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469936/e63c3a15-e9c1-21df-3f3b-e67ebf32b048.png)

出来上がりです！
回り込みが解決して、ちゃんとしたレイアウトになりましたね！
お疲れ様でした！

![スクリーンショット 2020-12-05 23.24.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469936/c985f596-c6ed-a487-eff6-d4ffc05705bf.png)

## おわりに

親要素の高さを保つだけなら、floatしているものと同じ高さの空ボックスを置くなど、いろんな対策があると思うのですが、
擬似要素で必ず親要素の末尾に空ボックスを置く方法であれば、どんな高さのレイアウト部分にも使用できて、再利用性が高いのがすごく便利だなと思いました！さすが老舗の方法…！

あと、図解すると、親要素から「浮く」って何？？？という疑問が解決して、スッキリしました！
（一応[HTMLの本](https://www.amazon.co.jp/dp/4774190640)読みながら描きましたが、解釈が間違ってたら教えてくださいmm！）

ここまでお読みいただき、ありがとうございました！