47歳でやむなくセミリタイア

病気のためセミリタイアをすることに。現在は週20時間程度のバイトをしています。その他、雑多なことを記録として書いています。

Yii2の使い方: cssについて勉強中 (vertical-align)

勉強中のcssのメモです。昨日書くつもりだったのですが、よくわからなくなってしまい今日になってしまいました。

CSSのvertical-alignについて嵌っています。vertical-align:middleは上下の真ん中にテキストなどを配置する指定ですが、色々と難しいです。googleでもvertical-alignと入れると、「vertical-align middle 効かない」と候補に出るくらいメジャーな問題です。

つまるところ、vertical-alignは、inline要素(画像や文字など)の前の要素の縦位置のどこに置くかという設定(1st とか、H2Oみたいな)なので、通常の位置指定には向いておらず、細工が必要になるということです。

やりたいこと

縦長の領域があります。その中に、横幅いっぱいのボックスを作って、その中心部にテキストを置きたい。以下のような感じです。
f:id:ekutajp:20190923101045p:plain

失敗パターン

まず、何も考えずにやってみます。

<div style="height:150px;width:200px;background:#bbb;">
    <div style="height:100px;background:#bbb;text-align:center;vertual-align:middle;">
        テスト
    </div>
</div>

縦長のボックスの中に、高さ100pxのボックスを入れて、縦(vertical-align)と横(text-align)のセンタリングを指定する。

結果

横のセンタリングは動作するが、縦の方は上に張り付いてしまう。これはvertical-alignはblock要素では有効にならないからです。
f:id:ekutajp:20190923003348p:plain

解決策その1 line-heightを使う

文字の高さを、領域の高さと同じだと騙します。その状態で文字を置くと、文字の高さの真ん中に配置されるので、上下の真ん中になります。

<div style="height:150px;width:200px;background:#888;">
    <div style="height:100px;line-height:100px;background:#ccc;text-align:center;">
        テスト
    </div>
</div>

問題点

文字が一行に収まらない場合、表示が崩れます。ウインドウサイズを縮めても改行されないような場合にだけ使用できる。

解決策その2 table-cellを使う

テーブル ()の場合にはvertical-alignが何故か使えます。このブロックはテーブルだと指定して騙します。

<div style="height:150px;width:200px;background:#888;">
    <div style="display:table-cell;height:100px;width:200px;background:#ccc;text-align:center;vertical-align:middle">
        テスト
    </div>
</div>

問題点

widthの指定が2箇所必要になるので、メンテナンス性は劣ります。今回のような単純な使い方だといいですが、問題が出る場合もあるようです。
display:table-cell;を安易に使うべきでない理由いろいろ - Qiita

解決策その3 blockはやめてflexを使う

CCS3で導入されたflexという指定を使用します。今後はこのやり方が主流となっていくはずです。

<div style="height:150px;width:200px;background:#888;">
    <div style="display:flex;height:100px;background:#ccc;align-items:center;justify-content:center;">
        テスト
    </div>
</div>

問題点

まだ対応が十分でないブラウザがあり、ブラウザによっては表示が崩れるかも。

結論

個人的なウェブサイトで使うなら解決策その3のflexを使います。
ただ、会社で使う時は、ブラウザの変な挙動を引きたくないので、その1、その2、その3の順番で使うでしょうね。今回のような場合は一行で収まるので、解決策その1を使います。

CSSは色々と罠があって難しいです。