【実務・中級編】dir属性による双方向テキスト(BiDi)の制御 – HTML実践ガイド

なぜそのテキストは「逆」に流れるのか? `dir` 属性とBiDi(双方向テキスト)制御の深淵

フロントエンドの現場で、「多言語対応」という言葉を聞いて、あなたはまず何を想像しますか? `i18n` ライブラリの導入? それとも翻訳ファイルの管理?

確かにそれらは重要ですが、実はもっと根源的な「テキストの表示順序」という罠が、時としてフロントエンドエンジニアを絶望の淵に突き落とします。そう、アラビア語やヘブライ語のように「右から左へ流れる」言語、いわゆる BiDi(Bidirectional:双方向)テキスト の扱いです。

今回は、MDNを眺めるだけでは決して見えてこない、ブラウザが裏側でどうやってテキストをレンダリングし、私たちが `dir` 属性でどう制御すべきか、その「泥臭いリアル」を解説します。

—

1. ブラウザは「テキストの並び」をどう判断しているのか

まず前提として、ブラウザのレンダリングエンジンは「Unicode双方向アルゴリズム(UAX #9)」という極めて複雑なルールに従って、テキストの流れる方向を決定しています。

通常、英語や日本語は「Left-to-Right(LTR)」ですが、アラビア語などは「Right-to-Left(RTL)」です。問題は、これらが混在したときです。例えば、RTLの文章の中に英語のブランド名が混ざると、ブラウザは「ここはLTRの塊だ」と自動判定し、インラインで反転させます。

この挙動を制御するのが `dir` 属性です。

dir属性の主要な値

  • `ltr`: 強制的に左から右へ。
  • `rtl`: 強制的に右から左へ。
  • `auto`: これこそが最強の武器。 テキストの最初の強い文字を解析し、方向を自動決定します。

—

2. なぜ `auto` を使うべきなのか?

多くの初心者は「言語がわかっているなら `ltr` や `rtl` を明示すればいい」と考えがちですが、それは実務では危険です。なぜなら、ユーザーが入力するコンテンツや、動的に差し込まれるCMSのデータには、どんな言語が混ざるか予測できないからです。

`dir=”auto”` を指定すると、ブラウザはテキスト内の最初の「方向性を持つ文字」を探しに行きます。例えば、先頭が英語なら `ltr`、アラビア語なら `rtl` と判断してくれます。

現場で直面する「カーソル移動の違和感」

`dir` 属性の指定を誤ると、UI上の見た目だけでなく、カーソル移動やテキスト選択の挙動が壊れます。 RTLのテキストに対して `ltr` を指定した状態でカーソルキーを叩くと、右に押したのに左へ進むような、ユーザーにとっての「UXの悪夢」が発生します。

—

3. 実践:現場で使える「BiDi制御」サンプル

以下は、チャットUIや掲示板など、ユーザー入力が混在する環境を想定した堅牢な実装例です。

Hello! مرحبا (Marhaba)


ここに動的なタイトルが入ります

—

4. Unicode制御文字という「最後の切り札」

時には、どうしてもブラウザの自動判定がうまくいかないケースがあります。例えば、「数字の羅列」はどちらの方向性も持たないため、アルゴリズムが迷走することがあります。

その場合、HTMLタグを汚さずにテキスト自体に意図を伝える Unicode制御文字 を埋め込むのがプロの手法です。

  • LRM (Left-to-Right Mark): `‎` (U+200E)
  • RLM (Right-to-Left Mark): `‏` (U+200F)

例えば、RTLの文章の末尾に、意図せずLTRの記号が回り込んで表示が崩れる場合、その記号の直前に `‏` を挿入することで、強制的にRTLの文脈を維持できます。

مرحبا يا صديقي ‏ (English Name)

—

結び:技術の「裏」を知れば、実装はもっと楽しくなる

「なぜ動かないのか」と悩む時間は、エンジニアにとって最も苦痛な時間です。しかし、ブラウザの内部仕様である「Unicode双方向アルゴリズム」の存在を知っていれば、その苦痛は「高度な制御」への挑戦に変わります。

まずはあなたの管理しているサイトの `p` 要素や `div` 要素に、一度 `dir=”auto”` を当ててみてください。それだけで、グローバルなユーザーに対するUIの品質が、一段階上のレベルへ引き上がるはずです。

現場からは以上です。もし「特定言語のフォントレンダリングが崩れる」なんて別の泥沼にハマったら、また相談してください。フロントエンドの闇は深いですからね。

コメント

タイトルとURLをコピーしました