※記事内の結論に誤りがあったため、更新しました。
この記事でアウトプットしたいこと
- 要素にfloatを指定したときのdisplayプロパティの挙動
- インライン要素にfloatを指定したときになぜwidthを指定しないと
text-align
が効かなくなるか
TL;DR
float
プロパティを設定すると、設定した要素のそのときのdisplay
プロパティの値によってdisplay
プロパティの値が変わるdisplay
がinline
のときはblock
になる
- インライン要素に
float
を設定すると、width
はshrink-to-fit
になる- 「内容にぴったりと合うように縮んだ」幅
- 現在の
display
プロパティの値を確認するのにFirefoxが便利
記事を作成しようと思ったきっかけ
text-align:center
が効かない!
<div class="box align-center"> <a href="" class="float-left">会社概要</a> <img src="" alt="イメージ図"> </div>
width
が設定されたdiv.box
内のaタグとimgタグの要素をtext-align:center
で中央揃えしようとしていた。
しかしながら、aタグの要素が中央に行かない。 下のCodePenを見てほしい。
See the Pen floatを設定するとdisplayプロパティがblockになる by itsumoonazicode (@itsumoonazicode) on CodePen.
結論は、aタグにfloatが設定されていたことによりblock要素になってしまったことが原因だったのだが、
そのことを知らなかったためハマってしまった...。
text-align
はインライン要素の行揃えを指定する
なので、blockになったaタグが中央揃えにならなかった。
text-align
をブロック要素に指定すると、要素内のインライン要素に作用する。
text-align - CSS: カスケーディングスタイルシート | MDN
であるなら、なぜaタグの文字列は中央揃えにならないのか?
float
を設定すると、display
の値が変化する
CSSの仕様書に以下のような記述がある。(翻訳版:更新日2020-08-02)
floatの指定値がnone以外ならば:displayの算出値は以下の規則に従う。
Visual formatting model: 9.7 Relationships between 'display', 'position', and 'float'(日本語訳)
指定値※ | 算出値 |
---|---|
inline |
block |
その他 | 指定値 |
※「指定値」は、そのときのdisplayの値を指す。
aタグのdisplayはinlineなので、floatを指定することでblockに変化する。
横幅が『「内容にぴったりと合うように縮んだ」幅』になる
であるなら、なぜaタグの文字列は中央揃えにならないのか?
ここからは上記に対して解説をする。
見るのは、floatを指定した要素の横幅である。
先述の通り、floatが指定されたaタグのdisplay
の値はblock
である。
なので、横幅は指定が無ければ親要素の横幅まで広がる。
そういう前提で実際にaタグの横幅を開発者ツールで確認してみると、、
なってない!!!
aタグの横幅は、文字の幅分しか取られていない。これに対してtext-align
を指定しても、思った通りの見た目にならないのは当然だ。
仕様書を見てみる。
10.3.5 非置換浮動要素の場合
'width'が'auto'として計算される場合、使用値は"適合するよう縮む"幅となる。
Visual formatting model details: 10.3.5 Floating, non-replaced elements(日本語訳)
※補足として、非置換要素と置換要素の説明を下に記載する。
- 非置換要素:「開始タグと終了タグに囲まれたテキストが表示される要素」
- 置換要素:「テキスト以外のものに置き換えられる要素(例えば画像や入力欄など)」
適合するように縮む幅の計算は、自動テーブルレイアウトアルゴリズムを使用したテーブルセルの幅の計算に似ている。おおまかには、明示的な改行が起きる場所以外で改行のないコンテンツを整形することによって望ましい幅を計算し、かつ望ましい最小の幅も計算する。
Visual formatting model details: 10.3.5 Floating, non-replaced elements(日本語訳)
「内容にぴったり合うよう縮む」とは、『(テーブルのセルと同じような挙動で)内容に応じて可能な限り小さく縮む』ことをいうようだ。
コードを書き換える
ここまで分かったところで、最初に提示した問題を解決すべくコードを書き換えてみる。
width
が設定されたdiv.box
内のaタグとimgタグの要素をtext-align:center
で中央揃えしようとしていた。しかしながら、aタグの要素が中央に行かない。
問題は、floatを指定したaタグのwidthがauto(初期値)だったために起こったものなので、widthを明示的に指定して解決する。
<div class="box align-center"> <a href="" class="box_link float-left"> Aタグ内の文字 </a> <img src="https://placehold.jp/150x150.png" alt=""> </div>
.box { /* 元々指定していたプロパティ */ width: 200px; } .box_link { width: 100%; }
以下のようにコードを変更した。
- aタグにwidthを指定するクラスを追加
- width:100%を追加
これでようやく期待通りのレイアウトにすることができた。
おまけ:現在のdisplay
プロパティの値を見るのにはFirefoxが便利
Firefoxの開発者ツールから Inspector > Layout > Box Model > Box Model Propertiesを見ると、以下のプロパティの値を確認できる。
- box-sizing
- display
- float
- line-height
- position
- z-index
ここから、現在の値を確認できる。
ChromeならComputedから見れるが、表示されるプロパティの数が多すぎるため閲覧性が低い。