サムネイルのように改行される問題について原因の可能性と対策を検証しました。
どんなときに起こるのか?
- 親要素が見出し要素
- Google Fontを使っている
- 子要素のdisplayにinine-blockまたはinline-flexを指定
- 親要素のfont-sizeに18px未満を指定
- 親要素のwidthにfit-contentを指定
- font-familyにGoogle Font以外の代替フォントを指定
- 文字が英語の場合は、2文字以上かつ文字間に半角空白や読点などがある
- 文字が日本語の場合は、2文字以上
↑上記の項目に全て当てはまる場合に1文字改行されました。要素の組み合わせによって発生しないパターンもあり謎でした。(例えば、親がdiv要素で子がa要素)
また、代替フォントもsans-serifでは発生するけど、monospaceではしなかったです。
試した限りコンテンツの文字が英語で、文字間に約物とか空白ない場合は大丈夫でした。
かなり狭い範囲の話
サンプルとコード
Safariでサンプルを確認してみてください↓
コードです↓
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Kaisei+HarunoUmi:wght@700&family=Noto+Sans+JP&display=swap" rel="stylesheet" />
<style>
body {
font-family: "Noto Sans JP", sans-serif;
}
.parent {
width: fit-content;
font-size: 16px;
}
.child {
display: inline-block;
}
</style>
</head>
<body>
<h3 class="parent">
<span class="child">Safariで1文字改行される</span>
</h3>
</body>
原因
自分では原因わからなかったので、X(旧Twitter)で投稿したところ、こびとさんが引用してくださったリプ欄に可能性の高そうな返信をいただきました↓
Safariでfit-contentを使用して、1行表示の時にswapで置き換えられると、起きかえられる前のデフォルト表示の時の幅より、Google fontの方が若干大きくなるからカラム落ちするんだった気がする
chickさんからのリプ
いただいたリプを元に検証してみます。
sans-serifとNoto Sans JPの切り替え動画↓
上記の動画は、font-familyにsans-serifまたはNoto Sans JPのみを指定した場合の動画です。
視聴すれば分かる通り、sans-serifの方が幅が小さいです。今回の場合のsans-serifは181.375pxで、Noto Sans JPは194.84375pxです。
font-family:"Noto Sans JP",sans-serif;
のように指定した場合、幅が181.375pxになります↓
以上よりSafariでは、Google Fontが読み込まれる前の代替フォント幅でfit-contentを計算しているのではないかと思いました。
対策
試してみて一行表示になった方法です↓
- 親要素のfont-sizeを18px以上にする
- 子要素に直接font-sizeを指定
- 子要素のdisplayをinline-block・inline-flex以外にする
- 子要素にfit-contentを指定する
- font-familyの指定をNoto Sans JPだけにする
- font-weightを700から500にする
上記のいずれかを試すと一行になりました。現実的な解決法は、②・③・④だと思います。
カード型のマークアップで見出し要素の中にa要素を使用するような場合に気をつけたいと思います。