使用 HTML dir 設定文字的基本方向,並使用 CSS flex-direction: row-reverse 反轉 flex 列的流向。從 Mac 為公開頁面排列卡片時,請先判斷你需要變更的是文字方向、項目順序還是對齊方式。

本指南假設你正在文字編輯器中編輯頁面的 HTML 與 CSS,並在桌面瀏覽器中預覽。任務是排列三個中性方塊——Alpha、Beta 和 Gamma——同時確保文字行為與文件順序符合預期。

各種方向設定實際會改變什麼?

HTML 的 dir 屬性描述元素文字的基本方向。明確指定的值為 ltr 和 rtl;auto 則要求瀏覽器根據內容判斷方向。WHATWG 鼓勵作者透過 HTML 表達文字方向,讓這項資訊在沒有 CSS 時仍然可用。HTML 標準:dir 屬性。

CSS direction 也會控制文字的基本方向,並參與版面配置行為。它會繼承,因此在容器上設定 direction: rtl 可能影響其後代元素。MDN 建議盡可能使用 HTML dir。請將 CSS 方向覆寫視為刻意變更文字方向的決定,而不是移動方塊的便捷方式。MDN:direction。

CSS flex-direction 控制 flex 容器的主軸。row 會沿著目前書寫模式的行內軸排列;row-reverse 則會對調主軸起點與終點的方向。它會改變項目的排列方向,同時保留項目的原始順序。W3C:Flex 流向。

這些機制會互相影響。在水平書寫模式下,ltr flex 列從左側開始,而 rtl flex 列從右側開始。加入 row-reverse 會反轉任一種起始方向。因此,row-reverse 不一定代表第一個項目會出現在右側。MDN:flex-direction。

哪項設定符合你的預期結果?

編輯前,請用具體文字寫下預期結果:「保留英文標籤原樣、將方塊的視覺順序反轉,並讓整組靠右。」這句話分別指出文字、項目流向和對齊方式的決定。

預期結果 合適的起點 檢查事項
設定內容的基本文字方向 HTML dir="ltr" 或 dir="rtl" 將它套用到文字需要該方向的範圍。
反轉 flex 列中所有項目的視覺排列順序 flex-direction: row-reverse 先檢查容器目前的方向。
將順序不變的列移至主軸終點側 justify-content: flex-end 確認有可供對齊的剩餘空間。
在各處變更有意義的順序 重新排列原始元素 確認新的閱讀順序合理。
在視覺上重新定位選定的項目 個別的 order 值 檢視視覺順序與原始順序之間的差異。

反轉與對齊的差異很重要。對於 ltr 列,justify-content: flex-end 可以將 Alpha、Beta 和 Gamma 一起放到右側,而不反轉它們的順序。對齊會分配主軸上的可用空間;flex-end 指的是 flex 容器主軸的終點側。如果彈性項目占用了該空間,對齊效果可能就會消失。MDN:justify-content。

如果讀者必須依特定順序接觸一系列內容,請在文件本身建立該順序。W3C 明確警告,不要使用 flex 反轉或 order 來彌補錯誤的原始順序。W3C:排序與方向。

變更頁面前,先預測四種組合

以下比較是根據已記載的軸向規則推導而來。假設使用 writing-mode: horizontal-tb、單一 flex 列、相同的 order 值,且原始順序為 Alpha、Beta、Gamma。「由左至右的外觀」描述方塊在螢幕上的實際位置。

容器方向 Flex 方向 第一個方塊從哪側開始 由左至右的外觀
ltr row 左側 Alpha、Beta、Gamma
ltr row-reverse 右側 Gamma、Beta、Alpha
rtl row 右側 Gamma、Beta、Alpha
rtl row-reverse 左側 Alpha、Beta、Gamma

當內容只是簡單的長方形時,第二列和第三列看起來可能一樣,但兩者的文字方向設定不同。第四種組合則解釋了一種常見的意外結果:同時套用 rtl 和 row-reverse 會產生由左至右的項目排列。MDN 說明了這種依方向而異的行為。MDN:flex-direction。

基本文字方向也會影響標點符號及方向性文字片段的順序。設定 rtl 並不會簡單地反轉英文單字中的每個字元。標籤可能仍然易於辨認,但標點符號可能出現在意料之外的位置。因此,純色方塊適合用來檢查方框的位置,卻不足以評估文字行為。MDN:dir 使用說明。

在 Mac 上試用完整的比較頁面

使用純文字編輯器將以下完整文件儲存為 direction-demo.html,然後在瀏覽器中開啟該檔案。此文件使用合成標籤與 CSS 長方形,不依賴外部資源。預期結果是根據已記載的規則推導而來;此範例並未宣稱經過瀏覽器測試。

<!doctype html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Direction and flex comparison</title>
  <style>
    body {
      font-family: system-ui, sans-serif;
      margin: 24px;
      color: #202020;
      background: #fff;
    }
    .row {
      display: flex;
      flex-direction: row;
      flex-wrap: nowrap;
      writing-mode: horizontal-tb;
      justify-content: flex-start;
      gap: 12px;
      max-width: 448px;
      padding: 12px;
      border: 1px solid #777;
      margin-bottom: 20px;
    }
    .reverse { flex-direction: row-reverse; }
    .tile {
      flex: 0 0 64px;
      padding: 16px 0;
      text-align: center;
      background: #e2ecf4;
    }
  </style>
</head>
<body>
  <h1>Direction and flex comparison</h1>
  <p>LTR with row</p>
  <div class="row" dir="ltr">
    <span class="tile">Alpha</span>
    <span class="tile">Beta</span>
    <span class="tile">Gamma</span>
  </div>
  <p>LTR with row-reverse</p>
  <div class="row reverse" dir="ltr">
    <span class="tile">Alpha</span>
    <span class="tile">Beta</span>
    <span class="tile">Gamma</span>
  </div>
  <p>RTL with row</p>
  <div class="row" dir="rtl">
    <span class="tile">Alpha</span>
    <span class="tile">Beta</span>
    <span class="tile">Gamma</span>
  </div>
  <p>RTL with row-reverse</p>
  <div class="row reverse" dir="rtl">
    <span class="tile">Alpha</span>
    <span class="tile">Beta</span>
    <span class="tile">Gamma</span>
  </div>
</body>
</html>

將四列與預測表比較。它們的原始順序完全相同,只有容器方向與反轉類別不同。明確指定水平書寫模式,讓此示範聚焦於一般的水平桌面情境。

接著,只將 justify-content: flex-start 改為 justify-content: flex-end,儲存並重新載入。各組應移至主軸另一側,同時保留每列的項目排列方向。這樣就能區分位置調整與反轉,而不必引入另一種文字方向設定。MDN:justify-content。

最後,還原對齊設定,並在每列的 Alpha 後加上句點。比較標點符號與方塊位置。這是用來探測文字方向的示範,並非建議為一般英文標籤指定 rtl。MDN 對基本方向的說明指出了為何邊界標點符號值得另外檢查。MDN:dir。

診斷實際版面配置中的意外結果

確認父元素是 flex 容器

檢查包含方塊的元素。只有當其 display 為 flex 或 inline-flex 時,flex-direction 才會生效。套用在一般區塊容器上的宣告不會建立 flex 版面配置。也請檢查是否有較後面的規則會在瀏覽器目前的寬度下變更有效值。MDN:flex-direction 說明。

新增另一種反轉前,先檢查繼承的方向

檢查容器及其祖先元素是否有 dir,再檢查是否有 CSS direction 宣告。省略 dir 時,方向通常會從父元素繼承;省略並不代表要求自動偵測。如果項目順序意外地從右側開始,繼承的方向可能就是原因。MDN:dir 的繼承行為。

避免將 dir="auto" 當成版面配置切換開關。WHATWG 將其定義為根據內容偵測方向,主要依據第一個具有明確方向性的字元,並建議僅在文字方向確實未知時使用。版面配置需求不應取決於恰好排在第一個的標籤。HTML 標準:dir 屬性。

區分項目反轉與列反轉

如果問題只在縮小視窗後出現,請檢查換行情況。row-reverse 會改變主軸的排列順序;wrap-reverse 會改變 flex 列的堆疊方向。預設的 nowrap 會維持單列,並可能造成溢出。這些是不同的控制項,因此除了初始桌面寬度,也要在窄視窗中測試。MDN:flex-wrap。

檢查個別的順序規則

檢查是否有任何方塊設有 order 值。Flex 版面配置會依整數值分組項目,數值最低者排在前面,數值相同的群組則保留原始順序。接著,反轉會改變此排序後序列的排列方向。在判定容器方向錯誤之前,先重設非預期的個別項目順序。MDN:排序 flex 項目。

保留變更前,先檢查閱讀順序

對於中性的裝飾方塊,視覺反轉可能就是全部需求。對於連結或控制項,請檢查原始碼中的順序,並逐一確認鍵盤焦點在元件中的移動。Flex 反轉本身不會改變循序導覽或語音朗讀順序。因此,視覺上反轉的群組仍可能保留原本的互動順序。W3C:Flex 流向。

運用這項檢查來判斷是否應變更原始碼。如果 Gamma、Beta、Alpha 才是預期的有意義順序,就按該順序排列元素。如果 Alpha、Beta、Gamma 仍是正確的閱讀順序,而只有呈現方式需要反轉,請以此區別來評估視覺排列。MDN 以可聚焦的連結示範了原始順序的行為。MDN:排序 flex 項目。

依據需求選擇機制:HTML dir 用於設定文字的基本方向,flex-direction 用於設定 flex 軸的流向,對齊則用來定位順序不變的項目。在保留結果前,請分別比較方塊位置、標點符號、換行和原始順序。這樣就能以可重複的方式,解決看起來只是反轉的版面配置問題。

來源