24.

HTML bdi要素 完全ガイド(双方向テキスト分離 / アラビア語ヘブライ語混在 / unicode-bidi / 実例)

編集
この記事の要点
  • <bdi>(Bi-Directional Isolation)は双方向テキストを周囲から分離する HTML5 要素
  • 左から右(LTR)の日本語/英語と、右から左(RTL)のアラビア語・ヘブライ語を混在表示するとき、表示順が壊れるのを防ぐ
  • ユーザー投稿名やコメントなど、テキスト方向が不明な動的コンテンツを安全に表示する用途で使う
  • CSS では unicode-bidi: isolate 相当の動作。<bdo> とは異なり方向を強制せず分離だけ行う
  • 対応状況: Chrome / Firefox / Safari / Edge いずれも対応済み

bdi 要素とは

<bdi>Bi-Directional Isolation)は HTML5 で導入された双方向テキストを周囲のテキストから分離する要素です。アラビア語やヘブライ語のような右から左(RTL)方向のテキストを、英語や日本語のような左から右(LTR)のテキストの中に埋め込むときに、文字の並びが期待通りにならない問題を解決します。

なぜ必要か — 双方向テキストの問題

HTML は Unicode の双方向アルゴリズム(UBA)に従ってテキストを表示します。RTL 言語の文字列が LTR 文脈に混入すると、句読点や数字の位置が乱れます。ユーザー名やタイトルのように方向が事前にわからない動的データでは特に問題になります。

<!-- bdi なし -- アラビア語の username で順序が崩れることがある -->
<p>ユーザー: ابو علي - 投稿数 123</p>

<!-- bdi で囲むと、周囲は LTR、内側は RTL として安全に分離 -->
<p>ユーザー: <bdi>ابو علي</bdi> - 投稿数 123</p>

基本構文

<ul>
  <li>1位 <bdi>太郎</bdi>: 1024点</li>
  <li>2位 <bdi>ابو علي</bdi>: 980点</li>
  <li>3位 <bdi>שלום</bdi>: 870点</li>
  <li>4位 <bdi>Smith</bdi>: 850点</li>
</ul>

上記の例では、ユーザー名がアラビア語・ヘブライ語でも、点数を含む周囲の文字列の並びは LTR のまま保たれます。

属性

属性意味デフォルト
dirテキスト方向を強制(ltr / rtl / auto)auto(内容から自動判定)

他の要素の dir 属性のデフォルトは inherit(親から継承)ですが、<bdi> だけはデフォルトが auto です。これが分離の本質です。

<bdi> と <bdo> の違い

要素意味用途
<bdi>双方向テキストを分離動的コンテンツ(ユーザー名等)
<bdo>テキスト方向を強制上書き意図的に表示方向を変える
<!-- bdo: 方向を強制(強制的に右から左にする) -->
<bdo dir="rtl">Hello World</bdo>
<!-- 表示: dlroW olleH -->

<!-- bdi: 分離だけ、方向は内容から自動判定 -->
<bdi>Hello World</bdi>
<!-- 表示: Hello World(LTR) -->

CSS との関係

<bdi> はおおよそ次の CSS と等価です。

bdi {
  unicode-bidi: isolate;
}

そのため、<span style="unicode-bidi: isolate"> でも同じ効果が得られますが、意味的に分離を示せる <bdi> の方が推奨されます。

典型ユースケース

  • 掲示板・SNS のユーザー名表示: どの言語の名前でも安全に表示
  • ニュースサイトの著者名: 国際記事で各国の名前を混在
  • ランキング表: 多言語のニックネームを並べる
  • コメント欄: 投稿者名や引用の方向が壊れない

ブラウザサポート

Chrome 16+、Firefox 10+、Safari 5.1+、Edge は全バージョンで対応。IE は非対応ですが、未対応ブラウザでも分離が効かないだけで内容は表示される(フォールバックは grace ful)ため、安心して使えます。

FAQ

Q: 普段使う必要はある?
A: 単一言語のみ扱うサイトでは不要。ユーザー投稿やコメント、人名など、方向が事前にわからない文字列を表示する場面で使います。

Q: dir="auto" を div につけても同じでは?
A: dir="auto" は方向の自動判定はしますが、分離はしません。<bdi> は方向判定+分離の両方を一度に行います。

Q: 中身が空でも意味がある?
A: 空の <bdi></bdi> 自体は意味を持ちません。常にユーザー名や動的データを内側に入れて使います。

Q: スタイルが当たらない
A: <bdi> はデフォルトで何も装飾されません。スタイルが必要なら CSS で bdi { color: ... } のように指定します。

歴史的経緯

HTML5 で双方向テキストの扱いは複雑になりました。アラビア語や日本語など複数言語のユーザー投稿が混在する SNS(Twitter、Facebook 等)の普及に伴い、テキスト方向が事前にわからない動的データを安全に表示する必要が高まり、<bdi> が標準化されました。Unicode の双方向アルゴリズム(UBA)が複雑なため、ライブラリで処理するのではなくマークアップで宣言的に解決できるのが大きなメリットです。

実装例 — SNS 風のコメント表示

<!-- 投稿者の言語が事前にわからない -->
<article>
  <header>
    <bdi class="author">{{ user.name }}</bdi>
    <span class="meta">- 3 分前</span>
  </header>
  <p><bdi>{{ post.body }}</bdi></p>
</article>

関連

  • bdo 要素 — テキスト方向を強制
  • dir 属性 — テキスト方向を指定
  • unicode-bidi (CSS) — テキスト方向の挙動を制御
  • direction (CSS) — ブロック方向の指定
  • Unicode 双方向アルゴリズム(UBA)
編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. h1~h6要素
  2. p要素
  3. blockquote要素
  4. q要素
  5. cite要素
  6. ins要素
  7. del要素
  8. HTML em 要素(強調)の使い方と strong との違い
  9. br要素
  10. abbr要素
  11. dfn要素
  12. pre要素で整形済みテキストを表示する
  13. code要素
  14. samp要素
  15. kbd要素
  16. var要素
  17. bdo要素
  18. sup要素で上付き文字を表示する
  19. sub要素
  20. mark要素
  21. data要素
  22. time要素
  23. wbr要素
  24. bdi要素

最近更新/作成されたページ