PPP's Blog

雑コード帳

floatを指定したインライン要素にtext-alignを適用する

※記事内の結論に誤りがあったため、更新しました。

この記事でアウトプットしたいこと

  • 要素にfloatを指定したときのdisplayプロパティの挙動
  • インライン要素にfloatを指定したときになぜwidthを指定しないとtext-alignが効かなくなるか

TL;DR

  • floatプロパティを設定すると、設定した要素のそのときのdisplayプロパティの値によってdisplayプロパティの値が変わる
    • displayinlineのときはblockになる
  • インライン要素にfloatを設定すると、widthshrink-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タグの横幅を開発者ツールで確認してみると、、

画像:floatを指定した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%;
}

以下のようにコードを変更した。

  1. aタグにwidthを指定するクラスを追加
  2. width:100%を追加

これでようやく期待通りのレイアウトにすることができた。

おまけ:現在のdisplayプロパティの値を見るのにはFirefoxが便利

Firefoxの開発者ツールから Inspector > Layout > Box Model > Box Model Propertiesを見ると、以下のプロパティの値を確認できる。

  • box-sizing
  • display
  • float
  • line-height
  • position
  • z-index

ここから、現在の値を確認できる。
ChromeならComputedから見れるが、表示されるプロパティの数が多すぎるため閲覧性が低い。

参考記事