🧱

それでも私が<wbr>でなくinline-blockで改行調整をする、たった1つの理由

2024/03/23に公開2

inline-block を使う理由、それは

入れ子構造を作れることにより、改行位置の優先順位をつけられるから!

スクリーンショット。2つのブロックで構成されている。どちらも「「この味がいいね」と君が言ったから七月六日はサラダ記念日」と表示されている。「やや狭のときは真ん中あたりで改行」と題されたブロックのものは上の句と下の句で2行であり、「激狭のときは句ごとに改行」と題されたブロックのものは5・7・5・7・7の5行に改行されている

詳しくは以降で説明します。

(前提)そもそも改行調整ってなんの話?

このタイトルを見て記事を開いた方であれば知っていると思いますが、一応説明です。

スペースで単語が区切られる欧文とは違い、日本語は単語の区切りがないので、改行すべき位置を機械的に判断できず、不自然な位置で改行されてしまうことがあります。そこで、見た目を整えるため、改行すべき位置を指定するための手法が必要になります。

他に詳しい記事がいくつもありますので、詳細はそちらを参照してください。

https://qiita.com/tamanyan/items/e37e76b7743c59235995

https://allabout.co.jp/gm/gc/23789/

代表的な改行調整の手法

<wbr> 要素

<wbr>要素は、改行してよい位置を表す要素です。
親要素に対して word-break: keep-all; を指定して基本的には改行されないようにすることで、<wbr>要素がある位置でのみ改行されるようになります。[1]

<p style="word-break: keep-all;">きよし<wbr />この夜</p>

<span> 要素 + display: inline-block;

改行されたくない範囲をspan 要素で囲み、display: inline-block; のスタイルを適用することでそのまとまりでは改行されないようにします。

<p>
  <span style="display: inline-block;">きよし</span
  ><span style="display: inline-block;">この夜</span>
</p>

個別に指定するのが面倒な場合、親要素のクラスで子要素すべてに適用する方法もあります。
以下は Tailwind CSS を使った例です。

<p class="[&_span]:inline-block"><span>きよし</span><span>この夜</span></p>

【非推奨】 <br> 要素 + display: none; (メディアクエリで出し分け)

使用例が多い手法ではありますが、非推奨の方法です。
この方法の場合、画面幅のみによって(文字の長さとコンテナの幅によらず)改行の有無が決まってしまうため、まだ改行せずに入り切る余白がある場合にも改行が入ってしまい不格好になりやすいです。そのためここでは比較対象にも含めません。

<p>きよし<br class="sm:hidden" />この夜</p>

想定しているシチュエーション

LP のファーストビューに入るキャッチコピー のような、 比較的短い、目立つ、キメのテキスト で使うことを想定しています。
「ここだけはどんな画面幅でもカッコよく見せたい!」 というときの調整です。

地の文すべてに対して使うことは想定していません。

改行位置には優先順位をつけたい

キャッチコピーのような目立つテキストにおいては、細かく改行位置を決めたいものです。

「この味がいいね」と君が言ったから七月六日はサラダ記念日

という俵万智さんの短歌を例にしてみます。

1 行で収まり切るコンテナ幅があれば 1 行で表示するとして、

「この味がいいね」と君が言ったから七月六日はサラダ記念日

1 行ではやや収まらないくらいのコンテナ幅のときはバランスよく 真ん中あたりで切りたい です。

「この味がいいね」と君が言ったから
七月六日はサラダ記念日

しかし、もっと狭いときはテキストのまとまり(句)ごとに切りたいです。

「この味が
いいね」と君が
言ったから
七月六日は
サラダ記念日

つまり、「から」の後ろの改行可能位置は、他の改行可能位置よりも優先順位が高いわけです。

<span> + inline-block であれば入れ子構造によって改行位置の優先順位をつけられる

前述の希望を叶えられるのが、<span> + inline-block の手法です ✨
<span> の入れ子構造により、 改行位置の優先順位 をつけることができます。

Tailwind Play でサンプルを作成しましたので、参考にご覧ください。

https://play.tailwindcss.com/flXq9wUpEc

<span> + inline-block での実装例(上)と、<wbr> での実装例(下)を比較したスクリーンショットを以下に示します。改行なしではギリギリ入り切らないくらいのコンテナ幅で表示しています。
前者は希望通り真ん中で改行できているのに対し、後者は最後の「サラダ記念日」だけが次の行に来ています。

ここで、前者の実装は以下のような HTML 構造になっています。前半と後半をそれぞれ span で囲み、さらにその中に span を入れることで、改行位置の優先順位をつけています。

入れ子構造をもたせた実装例
<!-- 改行調整に関するスタイルのみ抜粋 -->
<p class="[&_span]:inline-block">
  <span>
    <span>「この味が</span>
    <span>いいね」と君が</span>
    <span>言ったから</span>
  </span>
  <span>
    <span>七月六日は</span>
    <span>サラダ記念日</span>
  </span>
</p>

※上記の例では、構造のわかりやすさのために改行で整形していますが、表示に影響する空白が入ってしまうため、実際には改行を入れるべきではありません。

おわりに

<wbr> にはない、 <span> + inline-block による改行調整のメリットを紹介しました。
改行位置に優先順位をつけたくなったら思い出してみてください 😌

脚注
  1. 完全に余談なのですが、例示のために区切り位置が意味を変えてしまうような文章を探していたら、「ぎなた読み」という言葉を初めて知りました https://ja.wikipedia.org/wiki/ぎなた読み ↩︎

GitHubで編集を提案

Discussion

KeiKei

このやり方は、スクリーンリーダーを使用する場合に1つの文章として正しく認識されないことがあるようです。
Android の TalkBack 機能で検証した結果が以下になります。

かがんかがん

コメントありがとうございます!
読み上げの考慮について記事中で触れておらずすみません。

ご指摘のとおり、inline-blockで表示された要素は区切って読まれてしまうようです。
視覚上の調整と読み上げの考慮を両立する場合、読み上げ用のテキストを visually-hidden(Tailwindではsr-only)で入れておく手段が考えられます。

<p class="[&_span]:inline-block">
  <span class="sr-only">「この味がいいね」と君が言ったから七月六日はサラダ記念日</span>
  <span aria-hidden="true"><span>「この味が</span><span>いいね」と君が</span><span>言ったから</span></span
  ><span aria-hidden="true"><span>七月六日は</span><span>サラダ記念日</span></span>
</p>