sakamotoko blog

たぶんweb系の技術ブログ @skmtko

font-family の設定が原因で行ブロック内のテキストが縦中央揃えされない?

話したいこと

font-family:  Roboto, "Hiragino Kaku Gothic ProN", … ;

みたいな設定していたら、日本語のベースラインがずれて、テキスト + アイコン の縦がズレズレになってた。

調べてみたら、詳細な原因はよくわからんけど、フォントによって中央揃えしたときの揃い方だいぶ違いそうだったので、調べて分だけまとめる。

ちなみにデバイスヒラギノ入っている人の表示しか考慮できていないです。

きっかけ

inputRadioのコンポーネントを自作していたら、ラジオインプットのアイコンと、ラベルのテキストがどうしても揃ってくれなかった。

f:id:skmtko:20200628181504p:plain
こんな感じで、テキストが若干上がってしまう

いろいろ試してみたところ、特定のfont-family指定をしたときに縦揃いがしてくれなかった。

英数はmaterialUI推奨のRoboto をGoogleFontsから読み込んで使用、和文は我らのヒラギノを使う(デバイスにインストールされていれば..)ような 合字の指定がされていたが、その指定がなんか悪さをして文字が若干上にあがっていた。

調べたこと

マークアップと、スタイリングを再現して同様の状態を作った。

f:id:skmtko:20200628182441p:plain
font-family 指定なし

f:id:skmtko:20200628182524p:plain
Robot, Hiragino 指定

f:id:skmtko:20200628182623p:plain
Roboto, Noto Sans JP 指定

f:id:skmtko:20200628182721p:plain
Noto Sans JP 指定

font-famiryを適当に当てたとこと、ヒラギノとRobotoが共存してるときに、微妙な縦のズレが発生してるようだった。1pxくらいだけど

あと、Noto Sans JPと Robotoでも同じようなズレあった。 さらにNoto Sans JP のみのとき では逆方向に1pxずれてる謎。

ちなみに

icon-fontを使用して、アイコンとテキストを同じinline-blockの親を持つような構造にしてあげればアイコンとテキストでズレは生じませんでした。 こんな感じ↓

<span>
  <i />
  <span>text</span>
</span>

ちなみに2

ズレを起こしたのは以下みたいな感じで、フレックスで縦中央揃えをさせようとしてたけど、アイコンの中央と、inline-blockの中央が揃わなかったからずれちゃったんでしょう。

<span style="display: flex: align-items: center">
  <i>
  <span>text</span>
</span>

調べるのにつくたcodepenのpen

See the Pen baseline shifts because of font-family __ with checking text block size by kohei sakamoto (@eeonk) on CodePen.

各font-family のときのinline-blockのサイズの変わり方と、位置も見てみた

f:id:skmtko:20200630215553p:plain
各font-familyのときのinline-blockと行ブロックのサイズの変化

なんだか、inline-block内でも中央若干ずれてるやついるし、inline-block自体も行ブロックに対して中央にいないやついる。何も信じれなくなった。 そしてfont-size: 20px とか大きい指定をし始めると、特に縦ずれたりしなくなる。つらい

おそらく、フォントによってbase-lineが違うとかそんな理由で、縦のサイズが変わったり中心が動いたりするんだろうなと、無理やり納得することにします。詳しくはわからない。 font-size が大きくなると解決するのもよくわからんけど、font-size小さいときには、小数点以下の数値の扱いのせいできっとズレが生じるんだろうなと勝手に思っておきます。

調べるのにつくたcodepenのpen

See the Pen flex & text block size by kohei sakamoto (@eeonk) on CodePen.

解決案

ちなみに、原因調査前の応急処置としては、iconのheightを -2pxとかしてごまかした。(ラジオではサイズが可変する想定はなかったので)

その他の解決案としてはいかがかんがえられるのかなと言う感じ

  • font-family 見直す
    変えれるものなら...
  • icon-font使用して同じinline-blockの中に配置する
    ただし、レイアウトに制限掛かりそう親のブロックに対してテキストは左右中央、アイコンは右寄せとかつらそう
    f:id:skmtko:20200630222734p:plain
    こんな感じの使い方
  • テキストを lineheight: 1 にしてまう。
    テキストの折返しできなくなっちゃうけど
  • 気になる人には気持ち悪く感じるけど、諦める。

いろいろ調べてみたけど、気持ち悪い事実だけがわかって、最適な解決方法はイマイチわかんなかった。 くわしいひとおしえて