DK’s diary

プログラミング初学者による発信

floatプロパティで要素を横並びにした際にデザインが崩れる現象について

初めまして

初めまして、DKと申します!
プログラミング初学者ですがアウトプットの一つとして、学んだことを当ブログにて投稿していきたいと思います。
間違いやアドバイス等がありましたらご指摘いただけると幸いです。
よろしくお願いします!

今回のテーマ

今回はCSSのfloatプロパティで要素を横並びにした際に、デザインが崩れる現象の解決方法についてです。HTML/CSSの初学者が初めて直面する、イメージ通りにならない場面かと思います。
以下のデザインを目標に作成します。

f:id:dkdkdk3:20200329011558p:plain
完成図


1. float適用前
HTMLのソースコードは以下の通りです。横並びにする要素をそれぞれ、left-contentクラスとright-contentクラスとし、その親要素をcontentsクラスとします。(bodyタグ内のみの記述)

<body>
  <header></header>
  <main>
    <div class="contents">
      <div class="left-content">
      </div>
      <div class="right-content">
      </div>
    </div>
  </main>
  <footer></footer>
</body>

その後、CSSにheaderとfooter及びmainタグ内のクラスに適当に色付けをし、以下のデザインにしました。

f:id:dkdkdk3:20200329011703p:plain
float適用前


2. float適用後
CSSにfloatプロパティを適用します。(floatプロパティのみ記述)

.left-content {
  float: left;
}

.right-content {
  float: right;
}

するとこうなります。

f:id:dkdkdk3:20200329011733p:plain
float適用後
イメージと違いますよね?left-contentとright-contentは横並びになりましたが、それらの親要素であるcontentsが消えてしまいました。さらに、footerはheaderの真下にまでせり上がってきています。一体全体どういうことでしょう。

これは、floatという英語を日本語にすると理解しやすくなると思います。floatは日本語だと"浮く"という意味になります。CSSでは単純に横並びにするプロパティとして学習するかもしれませんが、実際は、浮くから横並びになるのです。
もう一度先ほどの結果を見てみましょう。

f:id:dkdkdk3:20200329011733p:plain
float適用後
この現象について順を辿るとこうなります。

  1. left-contentとright-contentがfloatプロパティによって浮き、左右に分かれた後にheaderにぶつかる。
  2. 親要素のcontentsは子要素が浮いたことにより高さを失い縮んでしまう。
  3. contentsが縮んだことにより、その下のfooterが上がってくる。

というイメージになります。
地球に住む私たちは、下方向(地面)に重力がありますが、HTML上には左上に重力のようなものがあると思ってください。その為に自分の上にあった要素が無くなるとせり上がってきてしまうのです。

clearfixの適用

この問題を解決するにはclearfixを適用します。デザインを固定したいものに適用するので、今回は親要素のcontentsに対して用います。ちなみに、fixには"固定する"という意味があるのでこれも覚えておくと記憶に定着しやすいですね。
まず、HTMLファイルのcontentsにclearfixクラスを付与します。

<body>
  <header></header>
  <main>
    <div class="contents clearfix">
      <div class="left-content">
      </div>
      <div class="right-content">
      </div>
    </div>
  </main>
    <footer></footer>
</body>

次にCSSファイルにclearfixセレクタを追加して、以下のようにプロパティを記述します。

.left-content {
  float: left;
}

.right-content {
  float: right;
}

.clearfix::after {
  content: "";
  clear: both;
  display: block;
}

すると、

f:id:dkdkdk3:20200329011558p:plain
clearfix適用後
完成系と同じになりました!
それぞれの意味についてですが、

  • ::after

clearfixのクラス名を付けた要素の直後に擬似要素を追加

  • content: "";

その擬似要素に任意の文字などを挿入できるが、今回は空に

  • clear: both;

floatによって消えてしまう高さを正常に
bothとすることが一般的

  • display: block;

追加された擬似要素をブロック要素に


個人的な理解の仕方としては、

”親要素contentsの直後に(::after)、ブロック要素の擬似要素を追加することで(display: block;)、下のfooterが上がってくるのを防いでいる。親要素contents自身はclear: both;によって正常な高さを維持している。”

と覚えています。content: "";はいらないのではと思うかもしれませんが、記述が無いデザインは修正されません。.clearfix::afterのafter部分にはbeforeとも記述できますが、この場合も修正されません。contentsの前に擬似要素を入れても意味がないからだと思います。

おわりに

今回の説明は以上になります!
初めての投稿どうだったでしょうか。頭の中では理解していたつもりでも、文字に起こすことで理解度が中途半端なものだなと感じることができました。週末にはこのような形でアウトプットを積極的に行なっていきたいと思います!!