CSS 和 JavaScript 無障礙最佳實踐
CSS 和 JavaScript,如果使用得當,也有可能提供無障礙的 Web 體驗;如果使用不當,它們可能會嚴重損害無障礙性。本文概述了一些 CSS 和 JavaScript 的最佳實踐,應該加以考慮,以確保即使是複雜的內容也儘可能無障礙。
| 預備知識 | 熟悉 HTML、CSS 以及對可訪問性概念的基本理解。 |
|---|---|
| 學習成果 |
|
CSS 和 JavaScript 無障礙嗎?
CSS 和 JavaScript 對無障礙的重要性不如 HTML 那麼直接,但它們仍然能夠幫助或損害無障礙性,這取決於它們的使用方式。換句話說,重要的是你要考慮一些最佳實踐建議,以確保你使用的 CSS 和 JavaScript 不會破壞文件的無障礙性。
CSS
讓我們從 CSS 開始。
正確的語義和使用者期望
可以使用 CSS 將任何 HTML 元素設計成任何樣子,但這並不意味著你應該這樣做。正如我們在HTML:無障礙的良好基礎一文中經常提到的,你應該儘可能使用適當的語義元素來完成工作。如果你不這樣做,可能會給所有人,尤其是殘障使用者,造成困惑和可用性問題。使用正確的語義與使用者期望有很大關係——元素根據其功能以某種方式呈現和行為,這些通用約定是使用者所期望的。
例如,如果開發人員沒有適當地使用標題元素來標記內容,螢幕閱讀器使用者就無法透過標題元素導航頁面。同樣,如果你對標題進行樣式設定,使其看起來不像標題,那麼標題就會失去其視覺目的。
總而言之,你可以更新頁面功能的樣式以適應你的設計,但不要更改太多,以至於它不再像預期的那樣呈現或行為。以下部分總結了要考慮的主要 HTML 功能。
“標準”文字內容結構
標題、段落、列表 — 頁面的核心文字內容
<h1>Heading</h1>
<p>Paragraph</p>
<ul>
<li>My list</li>
<li>has two items.</li>
</ul>
一些典型的 CSS 可能如下所示
h1 {
font-size: 5rem;
}
p,
li {
line-height: 1.5;
font-size: 1.6rem;
}
你應該
- 選擇合適的字型大小、行高、字間距等,使你的文字邏輯、清晰、閱讀舒適。
- 確保你的標題從正文中脫穎而出,通常像預設樣式一樣又大又粗。你的列表應該看起來像列表。
- 你的文字顏色應該與背景顏色形成良好的對比。
有關更多資訊,請參閱HTML 中的標題和段落以及CSS 文字樣式。
強調文字
賦予其所包裹文字特定強調的行內標記
<p>The water is <em>very hot</em>.</p>
<p>
Water droplets collecting on surfaces is called <strong>condensation</strong>.
</p>
你可能想為你的強調文字新增一些簡單的顏色
strong,
em {
color: #a60000;
}
然而,你很少需要以任何重要方式設定強調元素的樣式。粗體和斜體文字的標準約定非常容易識別,改變樣式可能會造成混淆。有關強調的更多資訊,請參閱強調和重要性。
縮寫
允許將縮寫詞、首字母縮略詞或首字母與它的完整形式關聯起來的元素
<p>
Web content is marked up using Hypertext Markup Language, or
<abbr>HTML</abbr>.
</p>
同樣,你可能想以某種簡單的方式設定它的樣式
abbr {
color: #a60000;
}
縮寫的公認樣式約定是虛線underline,顯著偏離此約定是不明智的。有關縮寫的更多資訊,請參閱縮寫。
連結
超連結 — 你在網路上前往新地方的方式
<p>Visit the <a href="https://www.mozilla.org">Mozilla homepage</a>.</p>
下面顯示了一些非常簡單的連結樣式
a {
color: red;
}
a:hover,
a:visited,
a:focus {
color: #a60000;
text-decoration: none;
}
a:active {
color: black;
background-color: #a60000;
}
標準連結約定是:在標準狀態下,帶有下劃線且顏色不同(預設:藍色);當連結之前已訪問過時,顏色會發生變化(預設:紫色);當連結被啟用時,顏色又會發生變化(預設:紅色)。此外,當滑鼠懸停在連結上時,滑鼠指標會變成手形圖示,並且當連結被聚焦(例如,透過 Tab 鍵)或啟用時,會收到高亮顯示。下圖顯示了 Firefox(虛線輪廓)和 Chrome(藍色輪廓)中的高亮顯示


你可以對連結樣式發揮創意,只要你在使用者與連結互動時持續提供反饋即可。當狀態改變時,肯定會發生一些事情,你不應該取消指標游標或輪廓——兩者對於使用鍵盤控制的使用者來說都是非常重要的無障礙輔助工具。
表單元素
允許使用者向網站輸入資料的元素
<div>
<label for="name">Enter your name</label>
<input type="text" id="name" name="name" />
</div>
你可以在我們的form-css.html示例中看到一些好的 CSS 示例(也可以線上檢視)。
你為表單編寫的大部分 CSS 將用於設定元素大小、對齊標籤和輸入,並使它們看起來整潔。
然而,你不應偏離表單元素在獲得焦點時預期的視覺反饋過多,這與連結基本相同(見上文)。你可以為表單焦點/懸停狀態設定樣式,以使此行為在不同瀏覽器中更一致或更好地適應你的頁面設計,但不要完全取消它——再次強調,人們依賴這些線索來幫助他們瞭解正在發生什麼。
表格
用於呈現表格資料的表格。
你可以在我們的table-css.html示例中看到一個很好的簡單表格 HTML 和 CSS 示例(也可以線上檢視)。
表格 CSS 通常用於使表格更好地融入你的設計並看起來不那麼醜陋。一個好主意是確保表格標題突出顯示(通常使用粗體),並使用斑馬條紋使不同的行更容易解析。
顏色和顏色對比度
為你的網站選擇配色方案時,請確保文字(前景)顏色與背景顏色形成良好的對比。你的設計可能看起來很酷,但如果色盲等視力障礙者無法閱讀你的內容,那就毫無意義。
有一種簡單的方法可以檢查你的對比度是否足夠大,不會造成問題。有許多線上對比度檢查工具,你可以輸入你的前景和背景顏色來檢查它們。例如,WebAIM 的顏色對比度檢查器使用簡單,並提供了你需要遵循 WCAG 顏色對比度標準的解釋。
注意:高對比度也能讓任何在明亮環境(例如陽光下)使用帶有光面螢幕的智慧手機或平板電腦的人更好地閱讀頁面。
另一個提示是不要僅僅依靠顏色來提供路標/資訊,因為這對於那些看不到顏色的人來說毫無用處。例如,與其用紅色標記必填表單欄位,不如用星號和紅色標記它們。
隱藏事物
在許多情況下,視覺設計要求並非所有內容都同時顯示。例如,在我們的選項卡式資訊框示例中(請參閱原始碼),我們有三個資訊面板,但我們正在將它們定位在彼此之上,並提供可以點選以顯示每個面板的選項卡(它也支援鍵盤訪問——你可以選擇使用 Tab 和 Enter/Return 鍵來選擇它們)。

螢幕閱讀器使用者並不關心這些——只要原始碼順序合理,並且他們可以訪問所有內容,他們就很高興。絕對定位(如本例所示)通常被認為是隱藏內容以實現視覺效果的最佳機制之一,因為它不會阻止螢幕閱讀器訪問內容。
另一方面,你不應該使用visibility: hidden或display: none,因為它們會向螢幕閱讀器隱藏內容。除非,當然,你有充分的理由希望此內容對螢幕閱讀器隱藏。
注意:僅針對螢幕閱讀器使用者的不可見內容提供了圍繞此主題的更多有用細節。
接受使用者可以覆蓋樣式
使用者可以用自己的自定義樣式覆蓋你的樣式,例如
- 請參閱 Sarah Maddox 的如何在 Firefox 中使用自定義樣式表 (CSS),獲取有關如何在 Firefox 中手動執行此操作的有用指南。
- 使用擴充套件程式可能更容易實現。例如,Stylus 擴充套件程式可用於Firefox,而 Stylish 則是Chrome 的對應項。
使用者可能出於各種原因這樣做。視力受損的使用者可能希望在他們訪問的所有網站上放大文字,或者嚴重色盲的使用者可能希望將所有網站設定為易於他們檢視的高對比度顏色。無論有什麼需求,你都應該對此感到滿意,並使你的設計足夠靈活,以便這些更改在你的設計中也能正常工作。例如,你可能希望確保你的主要內容區域能夠處理更大的文字(也許它會開始滾動以允許全部顯示),而不僅僅是隱藏它或完全破壞。
JavaScript
JavaScript 也可能破壞可訪問性,這取決於它的使用方式。
現代 JavaScript 是一種功能強大的語言,我們現在可以用它做很多事情,從簡單的內容和 UI 更新到成熟的 2D 和 3D 遊戲。沒有規定所有內容都必須對所有人 100% 可訪問——你只需要盡力而為,讓你的應用程式儘可能無障礙。
簡單的內容和功能可以說很容易實現無障礙——例如文字、影像、表格、表單和啟用功能的按鈕。正如我們在HTML:無障礙的良好基礎一文中探討的那樣,關鍵考慮因素是
- 良好的語義:為正確的工作使用正確的元素。例如,確保你使用標題和段落,以及
<button>和<a>元素 - 確保內容以文字形式提供,無論是直接作為文字內容、表單元素的良好文字標籤,還是文字替代項,例如影像的 alt 文字。
我們還研究了一個如何使用 JavaScript 來構建缺失功能的示例——請參閱重新構建鍵盤可訪問性。這不是理想的——實際上你應該為正確的工作使用正確的元素——但它表明在某些情況下,如果你無法控制所使用的標記,這是可能的。另一種改善非語義 JavaScript 驅動小部件可訪問性的方法是使用 WAI-ARIA 為螢幕閱讀器使用者提供額外的語義。下一篇文章也將詳細介紹這一點。
複雜功能,如 3D 遊戲,並不容易做到無障礙——使用 WebGL 建立的複雜 3D 遊戲將在 <canvas> 元素上渲染,該元素目前無法為嚴重視力障礙使用者提供文字替代或其他資訊。可以說,這樣的遊戲並不真正以這部分人群作為其主要目標受眾,期望你使其對盲人 100% 無障礙是不合理的。然而,你可以實現鍵盤控制,使其可供非滑鼠使用者使用,並使配色方案對比度足夠強,以便有色覺缺陷的人可以使用。
JavaScript 過多的問題
問題往往出現在人們過於依賴 JavaScript 的時候。有時你會看到一個網站,所有事情都用 JavaScript 完成——HTML 由 JavaScript 生成,CSS 由 JavaScript 生成,等等。這會帶來各種無障礙和其他問題,因此不建議這樣做。
除了為正確的工作使用正確的元素之外,你還應該確保為正確的工作使用正確的技術!仔細思考你是否需要那個閃亮的 JavaScript 驅動的 3D 資訊框,或者純文字是否也能做到。仔細思考你是否需要一個複雜的非標準表單小部件,或者一個文字輸入是否也能做到。如果可能的話,不要使用 JavaScript 生成你所有的 HTML 內容。
保持非侵入性
建立內容時,你應該記住非侵入式 JavaScript。非侵入式 JavaScript 的理念是,應儘可能將其用於增強功能,而不是完全構建功能——基本功能 ideally 應在沒有 JavaScript 的情況下工作,儘管有時這並不是一個選項。但同樣,很大一部分是儘可能使用內建瀏覽器功能。
非侵入式 JavaScript 的良好示例用途包括
- 提供客戶端表單驗證,在使用者無需等待伺服器檢查資料的情況下,快速提醒使用者其表單輸入存在問題。如果不可用,表單仍將正常工作,但驗證可能會較慢。
- 為 HTML
<video>提供可供僅鍵盤使用者訪問的自定義控制元件,以及在 JavaScript 不可用時可用於訪問影片的直接連結(預設的<video>瀏覽器控制元件在大多數瀏覽器中都無法透過鍵盤訪問)。
舉個例子,我們編寫了一個快速簡陋的客戶端表單驗證示例——請參閱form-validation.html(也請線上檢視演示)。在這裡你會看到一個簡單的表單;當你嘗試提交一個或兩個欄位為空的表單時,提交會失敗,並出現一個錯誤訊息框告訴你哪裡出了問題。
這種表單驗證是非侵入性的——在沒有 JavaScript 的情況下,你仍然可以非常流暢地使用表單,並且任何合理的表單實現都會同時啟用伺服器端驗證,因為惡意使用者很容易繞過客戶端驗證(例如,透過在瀏覽器中關閉 JavaScript)。客戶端驗證對於報告錯誤仍然非常有用——使用者可以立即瞭解他們所犯的錯誤,而不必等待往返伺服器和頁面重新載入。這是一個明確的可用性優勢。
注意:在此簡單演示中未實現伺服器端驗證。
我們也使這個表單驗證非常無障礙。我們使用了<label> 元素,以確保表單標籤與它們的輸入明確關聯,這樣螢幕閱讀器可以同時讀出它們
<label for="name">Enter your name:</label>
<input type="text" name="name" id="name" />
我們只在表單提交時進行驗證——這樣做是為了我們不會過於頻繁地更新 UI,從而可能混淆螢幕閱讀器(以及可能其他)使用者
form.onsubmit = validate;
function validate(e) {
errorList.textContent = "";
for (const testItem of formItems) {
if (testItem.input.value === "") {
errorField.style.left = "360px";
createLink(testItem);
}
}
if (errorList.hasChildNodes()) {
e.preventDefault();
}
}
注意:在此示例中,我們使用絕對定位而不是其他方法(例如可見性或顯示)來隱藏和顯示錯誤訊息框,因為它不會干擾螢幕閱讀器從中讀取內容。
真實的表單驗證會比這複雜得多——你會想要檢查輸入的姓名是否真的像姓名,輸入的年齡是否真的是數字並且是真實的(例如,非負且小於 4 位)。這裡我們只是實現了一個簡單的檢查,以確保每個輸入欄位都已填寫值 (if (testItem.input.value === ''))。
驗證執行完畢後,如果測試透過,則提交表單。如果存在錯誤 (if (errorList.hasChildNodes())),則我們停止表單提交(使用preventDefault()),並顯示所有已建立的錯誤訊息(見下文)。這種機制意味著錯誤只會存在錯誤時才會顯示,這對於可用性更好。
對於表單提交時沒有填寫值的每個輸入,我們都會建立一個帶有連結的列表項,並將其插入到 errorList 中。
function createLink(testItem) {
const listItem = document.createElement("li");
const anchor = document.createElement("a");
const name = testItem.input.name;
anchor.textContent = `${name} field is empty: fill in your ${name}.`;
anchor.href = `#${name}`;
listItem.appendChild(anchor);
errorList.appendChild(listItem);
}
每個連結都有雙重作用——它告訴你錯誤是什麼,此外你可以點選/啟用它,直接跳轉到相關的輸入元素並更正你的輸入。
此外,errorField 放置在源順序的頂部(儘管它在 UI 中使用 CSS 定位不同),這意味著使用者可以準確找出他們的表單提交出了什麼問題,並透過返回頁面開頭找到相關的輸入元素。
最後一點,我們在演示中使用了 WAI-ARIA 屬性來幫助解決由於內容區域不斷更新而無需重新載入頁面所導致的可訪問性問題(螢幕閱讀器預設不會捕捉到或提醒使用者)。
<div class="errors" role="alert" aria-relevant="all">
<ul></ul>
</div>
我們將在下一篇文章中詳細解釋這些屬性,該文章將更詳細地介紹WAI-ARIA。
注意:你們中的一些人可能會想到 HTML 表單具有內建的驗證機制,例如 required、min/minlength 和 max/maxlength 屬性(有關更多資訊,請參閱 <input> 元素參考)。我們最終在演示中沒有使用這些,因為它們的跨瀏覽器支援不穩定(例如,僅 IE10 及更高版本)。
注意:WebAIM 的可用且無障礙的表單驗證和錯誤恢復提供了有關無障礙表單驗證的一些進一步有用資訊。
其他 JavaScript 無障礙性問題
在實施 JavaScript 並考慮無障礙性時,還有其他需要注意的事項。我們會隨著發現而新增更多。
滑鼠特定事件
如你所知,大多數使用者互動都是在客戶端 JavaScript 中使用事件處理程式實現的,這使我們能夠響應某些事件的發生來執行函式。某些事件可能存在無障礙性問題。你將遇到的主要示例是滑鼠特定事件,如 mouseover、mouseout、dblclick 等。響應這些事件執行的功能將無法透過其他機制(如鍵盤控制)進行訪問。
為了緩解此類問題,你應該將這些事件與可以透過其他方式啟用的類似事件(所謂的裝置無關事件處理程式)結合起來——focus 和 blur 將為鍵盤使用者提供可訪問性。
讓我們看一個突出顯示何時這可能很有用的示例。也許我們想提供一個縮圖,當滑鼠懸停或聚焦時顯示影像的放大版本(就像你在電子商務產品目錄中看到的那樣)。
我們製作了一個非常簡單的示例,你可以在 mouse-and-keyboard-events.html 找到(另請參閱原始碼)。程式碼包含兩個顯示和隱藏放大影像的函式;這些函式由以下行作為事件處理程式執行
imgThumb.onmouseover = showImg;
imgThumb.onmouseout = hideImg;
imgThumb.onfocus = showImg;
imgThumb.onblur = hideImg;
前兩行分別在滑鼠指標懸停在縮圖上和停止懸停在縮圖上時執行這些函式。但這不允許我們透過鍵盤訪問縮放檢視——為了實現這一點,我們包含了最後兩行,它們在影像獲得焦點和失焦(焦點停止時)時執行這些函式。這可以透過在影像上使用 Tab 鍵來完成,因為我們在影像上包含了 tabindex="0"。
click 事件很有趣——它聽起來是依賴滑鼠的,但大多數瀏覽器會在連結或表單元素獲得焦點後按下 Enter/Return 鍵時,或者在觸控式螢幕裝置上點選此類元素時啟用 onclick 事件處理程式。然而,當你允許非預設可聚焦事件透過 tabindex 獲得焦點時,這預設不起作用——在這種情況下,你需要專門檢測何時按下該精確鍵(請參閱重新構建鍵盤可訪問性)。
總結
我們希望本文能為你提供足夠詳細的資訊和理解,瞭解網頁上 CSS 和 JavaScript 使用所涉及的無障礙性問題。
在下一篇文章中,我們將為您提供一些測試,您可以使用它們來檢查您對所有這些資訊的理解和掌握程度。