發布日期:2025 年 5 月 1 日
Chrome 137 以上版本支援 CSS reading-flow 和 reading-order 屬性。
這篇文章將說明這些屬性的設計原因,以及一些簡要的詳細資料,協助您開始使用這些屬性。
格線和彈性等版面配置方法改變了前端開發,但對部分使用者來說,這些方法的彈性可能會造成問題。在 DOM 樹狀結構中,很容易發生視覺順序與來源順序不符的情況。如果使用鍵盤瀏覽網站,瀏覽器會依據這個來源順序操作,因此部分使用者在瀏覽網頁時,可能會遇到非預期的跳轉情況。
為解決這個長期存在的問題,我們設計了 reading-flow 和 reading-order 屬性,並加入 CSS 顯示規格。
reading-flow
reading-flow CSS 屬性可控管彈性、格線或區塊版面配置中的元素向無障礙工具公開的順序,以及如何使用線性循序導覽方法取得焦點。
這個修飾符會採用一個關鍵字值,預設為 normal,可維持 DOM 順序的元素排序行為。如要在彈性容器中使用,請將值設為 flex-visual 或 flex-flow。如要在格線容器中使用,請將值設為 grid-rows、grid-columns 或 grid-order。
reading-order
reading-order CSS 屬性可讓您手動覆寫閱讀流程容器中的項目順序。如要在格線、彈性或區塊容器中使用這項屬性,請將容器的 reading-flow 值設為 source-order,並將個別項目的 reading-order 設為整數值。
Flexbox 範例
舉例來說,您可能有一個包含三個元素的彈性版面配置容器,這些元素以反向列順序排列,您也想使用 order 屬性重新隨機排序。
<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 鍵尋找上一個可聚焦的元素。 這會依來源順序顯示項目:一、二、三。
從使用者的角度來看,這並不合理,而且可能會造成混淆。如果我們使用無障礙空間導覽工具在頁面中瀏覽,也會發生同樣的情況。
如要修正這個問題,請設定 reading-flow 屬性:
.box {
reading-flow: flex-visual;
}
焦點順序現在為「一」、「三」、「二」。這與從左至右讀取英文時的視覺順序相同。
如果想保留原始的焦點順序 (反向順序),可以設定:
.box {
reading-flow: flex-flow;
}
焦點順序現在會與彈性順序相反: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。焦點順序仍為一到十二。
這是因為任何項目都沒有設定 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 屬性追蹤排序。
在先前的彈性範例中,如要取得與使用 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 的意見回饋要求。
請告訴我們
請試用這篇文章和 chrome.dev 上的reading-flow範例,並在網站上使用這些 CSS 屬性。如有任何意見回饋,請在 CSS 工作群組 GitHub 存放區中提出問題。如果對 tabindex 和焦點範圍設定行為有意見,請在 HTML WHATNOT GitHub 存放區中提出問題。歡迎提供這項功能的意見回饋。