font-size の指定位置によって要素の高さが変わる問題

こんにちは、たじまです。ブログの名前をデフォルトから変えてみました。

さて、今回は先日 CSS と戯れていた際に発見した謎とその正体を備忘録の意味も込めてブログに綴ります。わかってから見直すと何故わからなかったのかがわからない現象に陥りますが過去の自分を助けるべく綴ってみようと思います。

また、もし見当違いなことを言っている場合はそっと教えていただけると飛んで喜びます。

問題: font-size の位置によって要素の高さが変わる

ピュアな HTML+CSS で実装された UI を JSX で再実装していました。 すると旧 UI と新 UI で下の図のような要素の高さが違うという現象が起きました。

f:id:tjmschk:20220219163408j:plain
font-size の位置によっての要素の差がでた

JSX ではテキスト部分を実装する際に <Typogrphy /> という font に関わるスタイルを指定するコンポーネントを使いました。 そのため元の実装と比べると font-size を指定する箇所が移動し、結果見た目が変わってしまいました。

( ※ 見比べしやすいように図では横に並べていますが display: flex; などはかけていません。)

codepen でも再現してみたので触ってみてください。

See the Pen why font-size by Tajima Sachiko (@schktjm) on CodePen.


原因: 要素の高さ判定

何故今回のような違いがでてしまったのかというと、要素の高さの算出方法に原因がありました。 inline box コンテンツの場合、行ボックスの高さ計算は line-height x font-size で算出されます。

( 正確には影響しているスタイルなどによりもっと複雑です。正確な情報は公式ドキュメント参考にしてください*1 )

つまり、 wrapper の要素で font-size をしている要素の高さは次のように算出されます。

font-size x line-height
= 12px x 1.5
= 18px

f:id:tjmschk:20220219163505j:plain
wrapper の要素で font-size をつけた場合

しかし Text を囲んでる要素で font-size を指定している場合は、要素の font-size は親から継承されている値を使うため次のように算出されます。

font-size x line-height
= 16px x 1.5
= 24px

f:id:tjmschk:20220219163546j:plain
テキスト要素で font-size をつけた場合

その結果 font-size の指定箇所によって見た目に違いが発生していました。

問題解決方法

簡単にですが解決方法を挙げます。

height をつける

要素に高さが指定されていなかった結果、中身のコンテンツによって自動計算されていました。 そのため高さを指定すれば解決します。

フレックスコンテンツにする

高さを指定するものと基本は同じですが、フレックスボックスレベルに従って要素がレイアウトされるとフレックスコンテナーの高さに要素が引き伸ばされるため有効な手段です。今回の場合では wrapper 指定している CSSdisplay: inline-flex; を付け足すことで同じ高さになります。

そういうものだと理解する

もちろん理解すれば問題も発生しません。

おわりに

既存 UI の再実装により HTML+CSS の仕様についてひとつ詳しくなりました。複雑なのでブログには載せませんでしたが、 W3C のドキュメントにもっと詳しい inline box の高さの算出方法が載っていたため気になる方はそちらもご覧ください。

CSS Inline Layout Module Level 3

また文中に発生する単語は MDN や W3C の単語をそのまま引用しているだけなのでごちゃ混ぜになっている可能性があるため意味わかんねえよという時はそっと教えてください。

感想

実装した当時は何が起こっているのかさっぱりわかりませんでした。助けてくださったみんなには感謝の気持ちしかないです。 正しいソースを探すために MDN を飛び越えて W3C を初めて読み込んだのが楽しかったです。