網格佈局和無障礙性
HTML 是網站的內容層,我們用它來建立語義化、結構良好的文件。CSS 是表示層;我們應用 CSS 來為我們的內容建立所需的佈局等。二維網格結構是使用 CSS 網格佈局定義的。
儘管現代的 HTML 和 CSS 旨在建立語義化、可訪問的內容和設計,但有些方法仍可能用網格造成可訪問性問題。本文將探討可能出現的潛在問題,以及如何避免它們。
在 CSS 網格佈局中重新排序內容
我們已在這些指南中看到,CSS 網格佈局賦予了我們透過使用基於線的網格模板區域放置來重新排序頁面內容的能力。這種放置可以不考慮專案在源中的位置。此外,還有 order 屬性,它可以改變專案的自動放置方式。grid-auto-flow 屬性有一個 dense 值,這可能會使專案在視覺上脫離 DOM 順序。
CSS 網格佈局規範包含一個“重新排序和可訪問性”部分。該部分的引言詳細說明了當內容使用網格佈局進行視覺重排時,瀏覽器應該如何處理:
網格佈局賦予了作者對文件進行重新排列的強大能力。然而,這些能力不能替代正確的文件源順序。
order屬性和網格放置不影響非視覺媒體(如語音)中的順序。同樣,視覺上重新排列網格專案也不影響順序導航模式(如迴圈切換連結,參見tabindex)的預設遍歷順序。
如果你使用網格佈局在視覺上重新排序,這不會改變內容被螢幕閱讀器或其他文字轉語音使用者代理朗讀時的專案順序。此外,重新排序也不會改變 Tab 鍵的順序。這意味著使用鍵盤導航的人可能會在網站的連結間按 Tab 鍵切換,然後突然發現自己從文件頂部跳轉到底部,因為一個被重新排序的專案在 Tab 鍵順序中是下一個。
規範警告作者(CSSWG 對 Web 開發者的術語)不要進行這種重新排序。
作者必須只將
order和網格放置屬性用於視覺上的,而非邏輯上的內容重排。使用這些特性進行邏輯重排的樣式表是不符合規範的。
這在實踐中對於使用網格佈局進行設計意味著什麼呢?
視覺重排而非邏輯重排
任何時候你使用網格佈局——或 flexbox——重新排序時,你只進行了視覺重排。底層的原始碼控制著諸如文字轉語音和文件的 Tab 鍵順序等。我們可以透過一個例子來看看這是如何工作的。
在這個例子中,我們有一個包含五個專案的網格,每個專案都包含一個連結。這些專案透過基於線的放置屬性進行定位。我們將方框 1 放置在網格的第二行,因此它在視覺上顯示為列表中的第四個專案。如果我們用 Tab 鍵在連結間導航,Tab 鍵的順序仍然從方框 1 開始,因為它在原始碼中是第一個。
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
}
.box1 {
grid-column: 1;
grid-row: 2;
}
<div class="wrapper">
<div class="box box1"><a href="">One</a></div>
<div class="box box2"><a href="">Two</a></div>
<div class="box box3"><a href="">Three</a></div>
<div class="box box4"><a href="">Four</a></div>
<div class="box box5"><a href="">Five</a></div>
</div>
規範指出,在這種情況下,如果方框 1 在那個位置上確實在邏輯上是合理的,我們應該回到我們的 HTML 原始碼中進行更改,而不是使用網格佈局重新排序。這就是視覺重排與邏輯重排的含義;邏輯順序對我們文件的意義和結構很重要,我們應該確保我們保留這種結構。
我們應該如何處理網格佈局的可訪問性?
從規範中我們知道,需要確保我們的文件保持內容的邏輯順序。我們應該如何進行開發,以確保為不同的使用者以及他們與我們頁面的互動方式保持可訪問性呢?
- 從結構化和可訪問的文件開始
-
一個好的網格佈局應該意味著我們不需要為了得到想要的佈局而改變我們的文件原始碼。因此,你的頁面的起點應該是一個結構良好且可訪問的源文件。這通常也能為你的最小螢幕裝置提供一個良好的結構。當用戶在移動裝置上滾動瀏覽長文件時,該使用者的優先順序通常與原始碼中的優先順序相對應。
- 建立一個響應式且負責任的網格
-
在 HTML 中定義了堅實的文件結構後,你可以使用 CSS 在其上添加布局。你很可能會使用 媒體查詢 來為不同的螢幕尺寸和裝置進行更改,包括為更大的螢幕建立額外的列。網格在這裡非常有用。例如,在移動端原始碼中優先順序較低的元素可以在桌面佈局中被移動到側邊欄。這裡的關鍵是持續測試。一個好的測試方法是在文件中按 Tab 鍵切換。順序是否仍然合理?檢查你是否會以一種奇怪的方式從佈局的頂部跳到底部。這是一個跡象,表明你需要解決佈局中的某些問題。
- 迴歸原始碼
-
如果在設計過程中的任何時候,你發現自己正在使用網格來重新定位一個元素,請考慮是否也應該回到你的文件中並對邏輯順序進行更改。使用 CSS 網格佈局的好處在於,你應該能夠在原始碼中移動一個專案以匹配邏輯順序,而無需對你的佈局進行大的更改。我們作為開發者有責任記住要回到原始碼中更新它以保持邏輯順序。
網格和標記扁平化的危險
在 CSS 網格佈局中,以及在某種程度上在 CSS flexbox 中,另一個需要注意的問題是扁平化標記的誘惑。正如我們所發現的,一個專案要成為網格專案,它需要是網格容器的直接子元素。因此,當你在網格容器內有一個 <ul> 元素時,那個 ul 成為一個網格專案——其子元素 <li> 則不會。
grid-template-columns 和 grid-template-rows 的 subgrid 值解決了這個問題。它允許網格被網格專案繼承並向下傳遞到樹中。或者,在網格專案上設定 display: contents 會使其子元素成為網格專案。如果你將一個專案設定為 display: contents,它通常會建立的盒子會消失,而子元素的盒子會看起來像是提升了一個層級。
從一個結構良好的文件開始,是避免可訪問性問題的一個非常好的方法。
另見
- Flexbox 與鍵盤導航的脫節 和 (終究是人):可訪問性混音影片 via Léonie Watson (2016)
- 網格、內容重排和可訪問性 via CSS-tricks (2019)
display: contents不是 CSS 重置 via Adrian Roselli (2024)