發布日期:2025 年 5 月 1 日
CSS reading-flow
和 reading-order
屬性可在 Chrome 137 版中使用。本文將說明這些屬性設計背後的原因,並提供一些簡短的詳細資訊,協助您開始使用這些屬性。
格線和 Flex 等版面配置方法已改變前端開發作業,但它們的彈性可能會對部分使用者造成問題。很容易出現視覺順序與 DOM 樹狀結構中的來源順序不符的情況。使用鍵盤瀏覽網站時,瀏覽器會依照這個來源順序進行瀏覽,因此部分使用者在瀏覽網頁時,可能會遇到意外的跳轉情形。
reading-flow
和 reading-order
屬性已設計並新增至 CSS 顯示規格,以便解決這個長期存在的問題。
reading-flow
reading-flow
CSS 屬性可控制 Flex、格線或區塊版面配置中元素向無障礙工具公開的順序,以及使用線性順序導覽方法將焦點放在這些元素的方式。
這個屬性會採用一個關鍵字值,預設為 normal
,可保留元素的 DOM 排序行為。如要在 Flex 容器中使用,請將其值設為 flex-visual
或 flex-flow
。如要在格狀容器中使用,請將其值設為 grid-rows
、grid-columns
或 grid-order
。
reading-order
reading-order
CSS 屬性可讓您手動覆寫閱讀流程容器內的項目順序。如要在格狀、Flexbox 或區塊容器中使用此屬性,請將容器的 reading-flow
值設為 source-order
,並將個別項目的 reading-order
設為整數值。
Flexbox 範例
舉例來說,您可能有一個 Flex 版面配置容器,其中包含三個元素,並以相反的列順序排列,同時也想使用順序資源重新排列該順序。
<div class="box">
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</div>
.box {
display: flex;
flex-direction: row-reverse;
}
.box :nth-child(1) {
order: 2;
}
您可以嘗試使用 TAB 鍵瀏覽這些元素,找出下一個可聚焦的元素,並使用 TAB + SHIFT 鍵找出上一個可聚焦的元素。這會按照來源項目的順序:One、Two、Three。
從使用者的角度來看,這麼做毫無意義,而且可能會造成混淆。如果我們使用無障礙空間導覽工具瀏覽網頁,也會發生同樣的情況。
如要修正這個問題,請設定 reading-flow
屬性:
.box {
reading-flow: flex-visual;
}
焦點順序現在為:一、三、二。這與從左到右閱讀英文時的視覺順序相同。
相反地,如果您想保留焦點順序,並以相反的順序顯示,可以設定:
.box {
reading-flow: flex-flow;
}
焦點順序現在是反向的 Flex 順序:Two、Three、One。在兩種情況下,CSS order
屬性都會計算在內。
格狀版面配置範例
如要瞭解這項功能在格狀布局中的運作方式,請假設您正在使用 CSS 格狀布局自動放置項目,且有十二個可聚焦的區域。
<div class="wrapper">
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
<a href="#">Four</a>
<a href="#">Five</a>
<a href="#">Six</a>
<a href="#">Seven</a>
<a href="#">Eight</a>
<a href="#">Nine</a>
<a href="#">Ten</a>
<a href="#">Eleven</a>
<a href="#">Twelve</a>
</div>
您希望第五個子項佔據最上方的最大空間,其次是第二個子項,位於格線的中間。所有其他子項都可以依照欄範本自動放置在格線中。
.wrapper {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 100px;
}
.wrapper a:nth-child(2) {
grid-column: 3;
grid-row: 2 / 4;
}
.wrapper a:nth-child(5) {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
請嘗試使用 TAB 鍵瀏覽這些元素,找出下一個可聚焦的元素,然後使用 TAB + SHIFT 鍵找出上一個可聚焦的元素。這會按照來源順序排列項目:一到十二。
如要修正這個問題,請設定 reading-flow
屬性:
.wrapper {
reading-flow: grid-rows;
}
焦點順序現在為:五、一、三、二、四、六、七、八、九、十、十一、十二。按照視覺順序逐列顯示。
如果您想讓閱讀流程依照資料欄的順序進行,可以改用 grid-columns
關鍵字值。焦點順序就會變成五、六、九、七、十、一、二、十一、三、四、八、十二。
.wrapper {
reading-flow: grid-columns;
}
您也可以嘗試使用 grid-order
。焦點順序仍為 1 到 12。這是因為任何項目都未設定 CSS 訂單。
使用 reading-order
的區塊容器
reading-order
屬性可讓您指定在閱讀流程中應造訪的項目,覆寫 reading-flow
屬性設定的順序。當 reading-flow
屬性不是 normal
時,這項屬性只會對有效的閱讀流程容器生效。
.wrapper {
display: block;
reading-flow: source-order;
}
.top {
reading-order: -1;
inset-inline-start: 50px;
inset-block-start: 50px;
}
下列區塊容器包含五個項目。沒有任何版面配置規則會依來源順序重新排序元素,但有一個應優先造訪的流程外項目。
<div class="wrapper">
<a href="#">Item 1</a>
<a href="#">Item 2</a>
<a href="#">Item 3</a>
<a href="#">Item 4</a>
<a class="top" href="#">Item 5</a>
</div>
將此項目的 reading-order
設為 -1
後,焦點順序會先拜訪該項目,然後再改為讀取流程項目的來源順序。
如需更多範例,請前往 chrome.dev 網站。
與 tabindex 互動
以往開發人員會使用 HTML tabindex
全域屬性,讓 HTML 元素可供聚焦,並決定序列聚焦導覽的相對順序。不過,這項屬性有許多缺點和無障礙疑慮。主要問題是,使用正 tabindex 建立的 tabindex 排序焦點導覽,無法由無障礙樹狀結構辨識。如果使用方式不正確,可能會導致焦點順序不穩定,與螢幕閱讀器的體驗不符。如要修正這個問題,請使用 aria-owns HTML 屬性追蹤排序。
在先前的 Flex 範例中,如要取得與使用 reading-flow: flex-visual
相同的結果,您可以採取下列做法。
<div class="box" aria-owns="one three two">
<a href="#" tabindex="1" id="one">One</a>
<a href="#" tabindex="3" id="two">Two</a>
<a href="#" tabindex="2" id="three">Three</a>
</div>
不過,如果容器外部的另一個元素也有 tabindex=1
,會發生什麼情況?接著,系統會一起造訪所有含有 tabindex=1
的元素,然後再轉移至下一個遞增的 tabindex 值。這種跳躍式的連續導覽會導致使用者體驗不佳。因此,無障礙專家建議避免使用正 tabindex。我們在設計 reading-flow
時,曾嘗試修正這個問題。
設定 reading-flow
屬性的容器會成為焦點範圍擁有者。也就是說,它會將焦點導覽的範圍限制在容器內,以便在網路文件中移至下一個可聚焦的元素之前,先造訪容器內的每個元素。此外,其直接子項會使用 reading-flow 屬性排序,且系統會忽略正 tabindex,以便排序。不過,您還是可以在閱讀流程項目的子項上設定正 tabindex。
請注意,如果元素具有 display: contents
,且從其版面配置父項繼承 reading-flow
屬性,則該元素也會是有效的閱讀流程容器。設計網站時請留意這一點。如要進一步瞭解這項功能,請參閱我們對 reading-flow
和 display: contents
的意見回饋要求。
請告訴我們
請試試本文和 reading-flow
中的範例,並在網站上使用這些 CSS 屬性。如有任何意見回饋,請在 CSS 工作小組 GitHub 存放區中提出問題。如果您對 tabindex 和焦點範圍行為有具體意見,請將問題提交至 HTML WHATNOT GitHub 存放區。歡迎提供對這項功能的意見回饋。