- 原文地址:How to Keep Your CSS Grid Layouts Accessible
- 原文做者:Anna Monus
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:EmilyQiRabbit
- 校對者:xionglong58,hanxiansen
CSS Grid 能夠將元素放入有行和列的網格中,從而讓建立二維佈局成爲可能。有了它,你能夠自定義網格的任何形態,例如網格寬高、網格範圍、或者網格之間的間隙。可是,CSS Grid 可能會有訪問性不佳的問題,尤爲是對於那些使用屏幕閱讀器和僅使用鍵盤的用戶。本篇教程將會幫助你避免此類問題。css
「源順序獨立性」是 CSS Grid 強大優點之一。這意味着你不須要像使用 float 或者表格佈局那樣,在 HTML 中定義佈局結構。你可使用 CSS Grid 的排序和網格位置屬性改變 HTML 呈現的視覺效果。html
W3C 的 CSS Grid 文檔中的重排序和可訪問性章節,將源順序獨立性定義爲:前端
「經過將網格佈局與媒體查詢相結合,開發者可使用相同的語義標記,可是元素佈局的從新排列是脫離源代碼順序而獨立存在的,這樣就能夠同時在源代碼順序和渲染出的視覺效果兩個方面實現須要的佈局。」android
使用 CSS Grid,你能夠將邏輯順序和視覺順序解耦。源順序獨立性在不少時候都很是有用,可是它也有可能會破壞代碼的可訪問性。使用屏幕閱讀器和鍵盤的用戶都只能看到你 HTML 文件的代碼邏輯順序,可是沒法看到經過 CSS Grid 建立出來的視覺順序。ios
若是你的文檔很簡單,這一般不是什麼大問題,由於這時候源代碼邏輯順序和視覺順序基本是一致的。可是,比較複雜、不對稱、零散,或者使用了其餘創意佈局的文件一般就會對使用屏幕閱讀器或者鍵盤的用戶形成困惑。git
CSS Grid 有不少能夠改變文檔視覺順序的屬性:github
order
—— 在 flexbox 和 CSS Grid 規則中都有 order 屬性。它能夠改變 flex 或者 grid 容器中項目的默認排序。grid-row-start
,grid-row-end
,grid-column-start
,grid-column-end
。grid-row
,grid-column
,和 grid-area
(它是 grid-row
和 grid-column
的簡寫)。grid-template-areas
—— 指定已命名的網格區的位置。若是你想知道更多關於網格位置屬性的使用方法,能夠看看咱們以前關於網格區域的文章。如今,讓咱們看看視覺重排序是如何形成代碼可訪問性的問題的。web
這是一個簡單的網格佈局,只有幾個簡單的連接,因此你可使用鍵盤測試代碼:後端
<div class="container">
<div class="item-1"><a href="#">Link 1</a></div>
<div class="item-2"><a href="#">Link 2</a></div>
<div class="item-3"><a href="#">Link 3</a></div>
<div class="item-4"><a href="#">Link 4</a></div>
<div class="item-5"><a href="#">Link 5</a></div>
<div class="item-6"><a href="#">Link 6</a></div>
</div>
複製代碼
如今咱們再加入一些樣式。下面的 CSS 代碼將網格元素放入了三個寬度相同的列中。使用 grid-row
屬性,第一個元素被移動到了第二行的開始。ide
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 0.625rem;
}
.item-1 {
grid-row: 2;
}
複製代碼
在下面這個圖中,你能夠看到最終的視覺效果,其中 Link 1 被加上了一些特殊樣式以便突出說明。普通的用戶將會首先看到 Link 2,可是使用屏幕閱讀器的用戶將會從 Link 1 開始,由於他們聽從的是 HTML 代碼中定義的邏輯順序。
對於純鍵盤使用者,使用 tab 鍵瀏覽頁面也一樣困難,由於這樣依舊會從 Link 1 開始,也就是頁面的左下角(你能夠本身嘗試一下)。
解決方案很是簡單優雅。不要改變視覺順序,你只須要將 Link 1 移動到 HTML 文件的下面。這樣,源代碼順序和視覺順序就一致了。
<div class="container">
<div class="item-2"><a href="#">Link 2</a></div>
<div class="item-3"><a href="#">Link 3</a></div>
<div class="item-4"><a href="#">Link 4</a></div>
<div class="item-1"><a href="#">Link 1</a></div>
<div class="item-5"><a href="#">Link 5</a></div>
<div class="item-6"><a href="#">Link 6</a></div>
</div>
複製代碼
你不須要在 CSS 中爲 .item-1
添加任何關於 Grid 的屬性。由於你也不用改變默認的源代碼順序了,那麼你只須要爲網格容器定義屬性便可。
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 0.625rem;
}
複製代碼
看,儘管這個例子最終結果和之前同樣,如今它的可訪問性更高了。使用 tab 或者屏幕閱讀器都會從 Link 2 開始,邏輯上也遵循源代碼順序。
這裏有幾個通用的佈局模版,你可讓使用 CSS Grid 重排序屬性的代碼可訪問性更高。例如,「聖盃佈局」就是這樣一種模式。它包括一個頭部,一個主要內容區域,一個頁腳,還有兩個固定寬度的側邊欄,它們倆一個在左一個在右。
左邊欄佈局可能會爲使用屏幕閱讀器的用戶形成困惑。由於左邊欄在源代碼順序要要比主要內容區域靠前,而它則是使用屏幕閱讀器的用戶最早看到的內容。可是,一般狀況下,使用屏幕閱讀器的用戶開始閱讀的位置最好是主要內容。特別是當左邊欄主要包括的實際上是廣告,博客目錄,標籤雲,或者其餘一些不相關的內容。
CSS Grid 容許你改變 HTML 文件的源代碼順序,並將主要內容放在兩個側邊欄前面:
<div class="container">
<header>Header</header>
<main>Main content</main>
<aside class="left-sidebar">Left sidebar</aside>
<aside class="right-sidebar">Right sidebar</aside>
<footer>Footer</footer>
</div>
複製代碼
還有一些其餘可用的解決方案,來使用 CSS Grid 定義視覺順序的改變。大部分教程都會使用命名的網格區域,並使用 grid-template-areas
屬性對它們進行重排列。
下面的代碼是最簡單的解決方案,由於它只是爲視覺順序和源代碼順序不一樣的元素添加了幾個額外的規則。CSS Grid 有優秀的自動排列功能,可以把餘下的網格元素搞定。
.container {
display: grid;
grid-template-columns: 9.375rem 1fr 9.375rem;
grid-gap: 0.625rem;
}
header,
footer {
grid-column: 1 / span 3;
}
.left-sidebar {
grid-area: 2 / 1;
}
複製代碼
這樣,grid-column
讓 <header>
和 <footer>
區域橫跨整個屏幕(三列),而後 grid-area
(grid-row
和 grid-column
的簡寫)固定了左邊欄的位置。以下就是使用這些樣式後的樣子:
儘管聖盃佈局是一個相對簡單的佈局,你還可使用相同的邏輯來完成一些更復雜的佈局。要始終牢記頁面的哪一個部分是最重要的,哪部分是使用屏幕閱讀器的用戶在看到其餘內容以前可能最想看的。
某些狀況下,CSS Grid 也會對語義形成破壞;這也是影響可訪問性的一個方面。因爲 display: grid;
佈局僅被元素的直接子元素繼承,網格元素的子元素其實就不是網格佈局的一部分了。爲了節省工做量,開發者也許認爲將佈局扁平化是一個不錯的解決方案,因此他們就將全部但願包括在網格佈局內的元素都做爲網格容器的直接子元素。可是,若是一個佈局被認爲的扁平化了,文件的語義一般也就丟失了。
加入你想要建立一個元素展覽牆(好比圖片牆),在這裏,元素按照網格排列並被一個頭部和一個頁腳包圍。以下是帶語義的標籤寫法:
<section class="container">
<header>Header</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
<footer>Footer</footer>
</section>
複製代碼
可是若是你想要使用 CSS Grid,<section>
應該做爲網格容器,<h1>
、<h2>
和 <ul>
是網格元素。可是,列表內的元素不被包括在網格內,由於他們是網格容器子元素的子元素。
因此,若是你想要快速的完成工做,將佈局結構扁平化也許是一個不錯的主意,也就是讓全部的元素都做爲網格容器的子元素:
<section class="container">
<header>Header</header>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<footer>Footer</footer>
</section>
複製代碼
如今,你就能夠很輕鬆地使用 CSS Grid 建立出想要的佈局:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 0.625rem;
}
header,
footer {
grid-column: 1 / span 3;
}
複製代碼
一切看上去都很是好,可是文檔已經丟失了它最初的語義,因此:
最重要的規則是,你絕對不能爲了看上去好看而放棄語義。
目前的解決方案經過爲未排序的列表添加了 CSS 規則,建立出了嵌套的網格。
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 0.625rem;
}
.container > * {
grid-column: 1 / span 3;
}
ul {
display: inherit;
grid-template-columns: inherit;
grid-gap: inherit;
}
複製代碼
在以下例子中,你能夠看到嵌套的網格和父級網格是如何關聯的。元素按照指望的樣子排列出來了,可是此時,文檔始終保留着它的語義。
簡單的 CSS Grid 佈局可能不會致使可訪問性的問題。可是當你想要改變視覺順序或者建立多層網格的時候,問題就可能暴露出來。解決這些問題一般不會很麻煩,因此這樣作來修復那些可訪問性問題是很值得的,由於這樣你可以讓那些使用輔助工具的用戶更易讀懂你的內容。
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。