對於巢狀 HTML 文字,若要讓每個片語保有自己的方向而不影響相鄰文字,請選擇隔離。只有在刻意讓片語與周圍文字互動時才使用嵌入;若設計明確要求強制字元順序,則使用覆寫。
本指南協助在 Mac 上編輯 HTML 頁面的人選擇適當機制、保留巢狀標籤和標點符號,並在桌面瀏覽器中檢查結果。範例使用虛構的標籤、數字和幾何字元。
哪種機制符合版面需求?
先問兩個問題:瀏覽器是否應在片語內套用一般雙向文字排序?該片語是否應影響周圍文字的排序?這些決定可得出以下實用比較。MDN 的 unicode-bidi 參考資料說明了底層 CSS 行為。
| 需求 | 機制 | 建議的 HTML 作法 |
|---|---|---|
| 為已知方向的片語建立自己的邊界 | 隔離 | 使用既有的行內元素,搭配 dir="ltr" 或 dir="rtl" |
| 隔離方向未知的片語 | 自動判斷方向的隔離 | 使用 bdi,或使用既有的行內元素並搭配 dir="auto" |
| 建立仍會影響周圍排序的方向範圍 | 嵌入 | 使用 unicode-bidi: embed 的特殊 CSS 情況 |
| 強制字元順序並隔離結果 | 隔離式覆寫 | 使用 bdo,並明確指定 dir="ltr" 或 dir="rtl" |
| 強制字元順序,同時保留與周圍文字的互動 | 非隔離式覆寫 | 使用 unicode-bidi: bidi-override 的特殊 CSS 情況 |
一般 HTML 撰寫應以方向性標記作為起點。W3C 建議將每個反向片語緊密包在標記中,並透過巢狀標記表示巢狀片語。如此一來,文件中就能清楚看出預期的邊界。W3C:HTML 中的行內標記與雙向文字。
如何標記巢狀隔離文字?
為每個完整片語設定自己的方向邊界。如果既有的行內元素恰好只包含該片語,就在其中加入 dir。否則,新增一個 span。屬於片語的標點符號要留在包覆範圍內;周圍句子的標點符號則留在外面。W3C 將此稱為「緊密包覆」片語。W3C 的行內標記指南。
若要製作一個預期由右至左排列、並包含由左至右識別碼的合成形狀標籤,結構可如下方的示意片段:
<p dir="ltr">
Tile <span dir="rtl">● <span dir="ltr">A1 + B2</span> ■</span>: 12 items.
</p>
這裡有三個刻意設定的範圍:外層句子、形狀序列,以及巢狀識別碼。計數屬於句子,因此留在形狀序列之外。若只標記外層片語,內層識別碼就沒有自己的明確邊界。這種巢狀結構符合 W3C 對方向變更的建議。W3C 的巢狀片語指南。
插入的標籤方向未知時,bdi 可提供隔離,並預設自動偵測方向。沒有 dir 的一般 span 不會提供相同的預設行為。WHATWG 規定,bdi 的預設值是 auto,而不是以一般方式繼承方向。HTML 標準:bdi 元素。
自動判斷方向是根據第一個強方向性字元進行的啟發式判斷,並針對巢狀方向性元素規定了排除條件。它無法理解標籤的預期含義。因此,以 A1 開頭的標籤會提供由左至右的線索,即使後續內容暗示應採用不同的呈現方式。若已知需求,請明確指定方向。MDN:dir 全域屬性。
只包含形狀和數字的標籤需要特別留意:其中沒有強方向性字母。對於此處的一般行內範例,若自動判斷方向時找不到符合條件的字元,HTML 演算法會回退為由左至右。若這個合成序列必須以由右至左為基準方向,請指定 dir="rtl"。HTML 標準:dir 屬性。
何時適合使用嵌入和覆寫?
嵌入會建立另一個方向層級,並在其中保留一般字元排序。它的邊界也會對周圍文字產生方向性影響。隔離則讓內容擁有自己的範圍,同時使該序列對周圍文字呈現中性。W3C 規範明確區分這些內部與外部效果。CSS Writing Modes Level 3:嵌入與覆寫。
只有在這種外部方向影響屬於預期結果時才選擇嵌入。對於後面接著獨立計數的巢狀標籤,通常應使用隔離。僅僅多一層巢狀並不是選擇 embed 的理由:隔離的 span 本身也可以包含更多方向性 span。
覆寫會改變內部規則。它會依指定方向強制文字立即按順序排列,而不讓一般演算法解析其中的方向性文字段落。isolate-override 會在這種強制排序外加上隔離邊界。這些是不同的行為,不是用來修正一般片語的更強設定。MDN:unicode-bidi 值。
若要刻意示範字元順序,請使用 bdo 搭配 dir="ltr" 或 dir="rtl"。HTML 標準要求明確指定方向,並禁止在此元素上使用 auto。其呈現規則使用 unicode-bidi: isolate-override,因此目前 HTML 的 bdo 行為包含隔離。HTML 標準:bdo 元素,HTML 標準:雙向文字呈現。
這項區別對拉丁字母標籤很重要:由右至左的基準方向不代表「反轉每個拉丁字元」。覆寫可以強制這種順序。即便如此,各字形仍維持原本的方向;bdo 不會把字母形狀反向繪製。MDN:bdo 元素。
在 Mac 上試用完整的比較頁面
以下獨立頁面只需要瀏覽器和平文編輯器。前兩列比較一般方向處理和強制排序,其餘各列則呈現巢狀結構與邊界選擇。CSS 嵌入列用於示範機制;一般獨立標籤則應以 HTML 隔離列作為起點。
在 TextEdit 中選擇 File > New,然後選擇 Format > Make Plain Text。貼上下方完整程式碼。選擇 File > Save,將檔案命名為 bidi-demo.html,若出現提示則選擇 Use .html。這些是 Apple 說明的建立 HTML 檔案步驟。接著在桌面瀏覽器中開啟儲存的檔案。Apple:在 Mac 上使用 TextEdit 處理 HTML 文件。
<!doctype html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bidi boundary comparison</title>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 44rem;
margin: 2rem auto;
padding: 0 1rem;
line-height: 1.7;
}
.sample {
border: 1px solid #777;
padding: 0.75rem;
}
.scope {
background: #eeeeee;
outline: 1px dotted #555;
}
.embedding {
direction: rtl;
unicode-bidi: embed;
}
</style>
</head>
<body>
<h1>Bidi boundary comparison</h1>
<h2>Ordinary right-to-left base</h2>
<p class="sample">Before <span class="scope" dir="rtl">ABC</span> after.</p>
<h2>Forced right-to-left sequence</h2>
<p class="sample">Before <bdo class="scope" dir="rtl">ABC</bdo> after.</p>
<h2>Nested isolation</h2>
<p class="sample">Tile <span class="scope" dir="rtl">● <span dir="ltr">A1 + B2</span> ■</span>: 12 items.</p>
<h2>Embedding comparison</h2>
<p class="sample">Tile <span class="scope embedding">● <span dir="ltr">A1 + B2</span> ■</span>: 12 items.</p>
<h2>Automatic isolated direction</h2>
<p class="sample">Tile <bdi class="scope">A1 (12)</bdi>: 12 items.</p>
</body>
</html>
先檢視前兩列,不要進行任何變更。一般方向 span 應保留 ABC 的由左至右字母順序。從左側邊緣讀取時,覆寫列應顯示 CBA。這是根據已說明機制推得的預期,並非實際回報的瀏覽器測量結果。MDN:bdo 行為。
接著比較巢狀隔離列和嵌入列。檢視形狀序列及其邊界上的標點符號,同時保持文字和計數不變。即使特定範例看起來相同,使用的機制仍不一樣:隔離和嵌入不保證每個字串都會產生明顯不同的結果。文件所述的差異在於該範圍如何參與周圍的雙向文字解析。W3C:CSS Writing Modes Level 3。
要進行實用的邊界測試,請將冒號移到外層方向 span 內,儲存後重新載入,再將它移回外面。你正在變更哪個片語包含該標點符號,因此應根據預期歸屬來評估結果。最後,縮小瀏覽器視窗,檢查句子換行時相同的邊界。
背景和點狀外框可標示受測的 span,作為檢查輔助。它們不會設定方向或隔離。
如何診斷看起來仍然不對的結果?
從受影響最小的片語開始往外檢查。一次變更多個方向屬性,會讓你難以找出是哪個邊界造成結果。
- 檢查包覆元素。 它是否包含完整標籤,而且只包含該標籤?除非句子標點符號和計數屬於標籤,否則應留在外面。
- 檢查巢狀片語。 另一個片語中的獨立方向識別碼,可能需要自己的
dir包覆元素。 - 檢查自動判斷方向。 若已知預期的基準方向,請將
auto替換為明確方向。這對合成形狀和數字特別有用。 - 檢查覆寫。 若字元順序意外地被強制,請檢查
bdo和 CSSunicode-bidi宣告。 - 檢查 CSS 串接。 作者規則可能會取代瀏覽器的方向樣式。移除實驗用的雙向文字規則,然後重新測試 HTML 標記。
前兩項檢查遵循W3C 的包覆與巢狀結構指南。自動判斷方向的檢查遵循MDN 的 dir 說明文件;最後幾項則遵循HTML 呈現規則。
另外也要區分排序和對齊。text-align: right 會將行內內容置於區塊的右緣,但不會建立隔離片語。text-align: start 會依區塊方向決定位置,因此基準方向變更時,所使用的邊緣也可能改變。請分開診斷字元順序問題和文字行的位置。MDN:text-align。
在相容性方面,WHATWG 文件指出 bdi 和 bdo 均受目前所有瀏覽器引擎支援。這不代表所有舊版瀏覽器或嵌入式檢視器都支援。檢查其他呈現環境時,請測試實際目標,並保留方向性 HTML 標記:MDN 建議使用此方法,而非只用 CSS 隔離,因為樣式可能會遭忽略。HTML 標準:文字層級語意,MDN:bdi 使用說明。
最後,為每個巢狀片語明確決定其基準方向、邊界,以及內部字元順序是否應維持一般方式。若是獨立標籤,請從隔離開始。只有在版面需要其特定文件所述行為時,才保留嵌入或覆寫。
來源
- HTML 中的行內標記與雙向文字 — W3C。
- CSS Writing Modes Level 3 — W3C。
- HTML 標準,網頁開發者版:文字層級語意 — WHATWG。
- HTML 標準:呈現 — WHATWG。
- HTML 標準:
dir屬性 — WHATWG。 unicode-bidiCSS 屬性 — MDN Web Docs。bdi:HTML 雙向隔離元素 — MDN Web Docs。bdo:HTML 雙向文字覆寫元素 — MDN Web Docs。dirHTML 全域屬性 — MDN Web Docs。text-alignCSS 屬性 — MDN Web Docs。- 在 Mac 上使用 TextEdit 處理 HTML 文件 — Apple。