CSS 和 JavaScript 可訪問性最佳實踐

CSS 和 JavaScript 在正確使用的情況下,也具有提供無障礙網路體驗的潛力,或者在誤用時會嚴重損害無障礙性。本文概述了一些 CSS 和 JavaScript 最佳實踐,應考慮這些最佳實踐以確保即使是複雜的內容也儘可能地易於訪問。

先決條件 對 HTML、CSS 和 JavaScript 的基本瞭解,以及對 什麼是無障礙性 的理解。
目標 熟悉在網頁文件中適當使用 CSS 和 JavaScript 以最大程度地提高無障礙性,而不是降低無障礙性。

CSS 和 JavaScript 可訪問嗎?

CSS 和 JavaScript 在無障礙性方面沒有 HTML 那樣直接的重要性,但它們仍然能夠幫助或損害無障礙性,具體取決於它們的使用方式。換句話說,重要的是您要考慮一些最佳實踐建議,以確保您對 CSS 和 JavaScript 的使用不會破壞文件的無障礙性。

CSS

讓我們從 CSS 開始。

正確的語義和使用者預期

可以使用 CSS 使任何 HTML 元素看起來像 任何東西,但這並不意味著您應該這樣做。正如我們在 HTML:無障礙性的良好基礎 文章中經常提到的那樣,您應該儘可能使用適合該工作的語義元素。如果您沒有這樣做,它會導致每個人,尤其是殘疾使用者,感到困惑和可用性問題。使用正確的語義與使用者預期有很大關係——元素的外觀和行為方式取決於它們的功能,使用者期望這些常見約定。

例如,如果開發人員沒有適當地使用標題元素來標記內容,螢幕閱讀器使用者就無法透過標題元素導航頁面。同樣,如果您將標題的樣式設定為看起來不像標題,那麼標題就會失去其視覺目的。

底線是,您可以更新頁面功能的樣式以適合您的設計,但不要更改太多,以至於它不再看起來或表現得像預期那樣。以下部分總結了要考慮的主要 HTML 功能。

“標準”文字內容結構

標題、段落、列表——頁面核心文字內容

html
<h1>Heading</h1>

<p>Paragraph</p>

<ul>
  <li>My list</li>
  <li>has two items.</li>
</ul>

一些典型的 CSS 可能看起來像這樣

css
h1 {
  font-size: 5rem;
}

p,
li {
  line-height: 1.5;
  font-size: 1.6rem;
}

您應該

  • 選擇合理的字型大小、行高、字距等,使您的文字邏輯、易讀且舒適。
  • 確保您的標題與正文文字區分開來,通常像預設樣式那樣大而粗體。您的列表應該看起來像列表。
  • 您的文字顏色應與您的背景顏色形成良好對比。

有關更多資訊,請參閱 HTML 文字基礎文字樣式

強調文字

內聯標記,賦予其包裝的文字特定強調

html
<p>The water is <em>very hot</em>.</p>

<p>
  Water droplets collecting on surfaces is called <strong>condensation</strong>.
</p>

您可能希望在強調文字中新增一些簡單的顏色

css
strong,
em {
  color: #a60000;
}

但是,您很少需要以任何重要方式為強調元素設定樣式。粗體和斜體文字的標準約定非常容易識別,更改樣式會導致混亂。有關強調的更多資訊,請參閱 強調和重要性

縮寫

允許將縮寫、首字母縮略詞或縮寫與其擴充套件關聯的元素

html
<p>
  Web content is marked up using Hypertext Markup Language, or
  <abbr>HTML</abbr>.
</p>

同樣,您可能希望以某種簡單的方式對其進行樣式設定

css
abbr {
  color: #a60000;
}

縮寫的公認樣式約定是帶點下劃線,不建議大幅偏離它。有關縮寫的更多資訊,請參閱 縮寫

超連結——您在網路上到達新地方的方式

html
<p>Visit the <a href="https://www.mozilla.org">Mozilla homepage</a>.</p>

下面顯示了一些非常簡單的連結樣式

css
a {
  color: #ff0000;
}

a:hover,
a:visited,
a:focus {
  color: #a60000;
  text-decoration: none;
}

a:active {
  color: #000000;
  background-color: #a60000;
}

標準連結約定在標準狀態下是帶下劃線和不同顏色(預設:藍色),連結被訪問後是另一種顏色變化(預設:紫色),啟用連結時又是另一種顏色(預設:紅色)。此外,當滑鼠懸停在連結上時,滑鼠指標會變為指標圖示,並且連結在獲得焦點(例如透過製表符)或啟用時會收到突出顯示。下圖顯示了 Firefox(虛線輪廓)和 Chrome(藍色輪廓)中的突出顯示

Screenshot of a list of links in Firefox browser. The list contains 4 items. The second list item is highlighted using a blue dotted outline when it is focussed via tabbing.

Screenshot of a list of links in Chrome browser. The list contains 4 items. The third list item is highlighted using a blue outline when it is focussed via tabbing.

您可以對連結樣式進行創意設計,只要您在使用者與連結互動時繼續向用戶提供反饋。在狀態改變時肯定應該發生一些事情,並且您不應該去掉指標游標或輪廓——它們都是使用鍵盤控制的人非常重要的輔助功能。

表單元素

允許使用者將資料輸入網站的元素

html
<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 來選擇它們)。

Three tab interface with Tab 1 selected and only its contents are displayed. The contents of other tabs are hidden. If a tab is selected, then it's text-color changes from black to white and the background-color changes from orange-red to saddle brown.

螢幕閱讀器使用者不關心所有這些——只要源順序合理,並且他們可以訪問所有內容,他們就會對內容感到滿意。絕對定位(如在本示例中使用)通常被認為是出於視覺效果隱藏內容的最佳機制之一,因為它不會阻止螢幕閱讀器訪問內容。

另一方面,您不應該使用 visibility: hiddendisplay: none,因為它們會將內容隱藏在螢幕閱讀器之外。當然,除非有充分的理由要將此內容隱藏在螢幕閱讀器之外。

注意: 僅供螢幕閱讀器使用者使用的不可見內容 提供了有關此主題的更多有用細節。

接受使用者可以覆蓋樣式

使用者可以使用自己的自定義樣式覆蓋您的樣式,例如

使用者可能出於各種原因這樣做。視障使用者可能希望在他們訪問的所有網站上將文字放大,或者患有嚴重色覺異常的使用者可能希望將所有網站設定為高對比度顏色,這樣他們更容易看到。無論出於何種需要,您都應該對此感到自在,並使您的設計足夠靈活,以便這些更改能夠在您的設計中正常工作。例如,您可能希望確保您的主要內容區域可以處理更大的文字(也許它會開始滾動以允許所有內容都可見),並且不會僅僅隱藏它,或者完全中斷。

JavaScript

JavaScript 也可能破壞無障礙性,具體取決於它的使用方式。

現代 JavaScript 是一種功能強大的語言,我們現在可以用它做很多事情,從簡單的內容和 UI 更新到功能齊全的 2D 和 3D 遊戲。沒有規定說所有內容都必須對所有人 100% 可訪問——您只需要盡力而為,並使您的應用程式儘可能地易於訪問。

簡單的內容和功能可以說很容易使之變得無障礙——例如文字、影像、表格、表單和用於啟用功能的按鈕。正如我們在 HTML:無障礙性的良好基礎 文章中所述,關鍵考慮因素是

  • 良好的語義:為正確的工作使用正確的元素。例如,確保您使用標題和段落,以及 <button><a> 元素
  • 確保內容以文字形式提供,無論是直接作為文字內容,還是表單元素的良好文字標籤,或者 文字替代,例如影像的 alt 文字。

我們還研究瞭如何在缺少功能的地方使用 JavaScript 來構建功能的示例——請參閱 重建鍵盤無障礙性。這不是理想的——實際上您應該為正確的工作使用正確的元素——但這表明在某些情況下,如果您無法控制所使用的標記,這仍然是可能的。另一種方法是使用 WAI-ARIA 為非語義 JavaScript 驅動的視窗小部件提供額外的語義,從而提高螢幕閱讀器使用者的無障礙性。下一篇文章也將詳細介紹這一點。

像 3D 遊戲這樣的複雜功能並不容易實現無障礙性——使用 WebGL 建立的複雜 3D 遊戲將在 <canvas> 元素上渲染,該元素目前還沒有提供文字替代或其他資訊以供嚴重視力障礙使用者使用的功能。可以說,這類遊戲並沒有將這類人群作為其主要目標受眾,要求你使其對盲人 100% 無障礙是不合理的。但是,你可以實現 鍵盤控制,使其可供非滑鼠使用者使用,並使顏色方案對比度足夠高,以便色覺缺陷者可以使用。

過多的 JavaScript 問題

問題通常出現在人們過度依賴 JavaScript 的時候。有時你會看到一個網站,其中所有內容都是用 JavaScript 實現的——HTML 由 JavaScript 生成,CSS 由 JavaScript 生成,等等。這會帶來各種無障礙性和其他問題,因此不建議這樣做。

除了使用正確的元素來完成正確的工作之外,你還要確保你正在使用正確的技術來完成正確的工作!仔細考慮一下你是否需要那個閃閃發光的 JavaScript 驅動的 3D 資訊框,或者簡單的純文字是否可以。仔細考慮一下你是否需要一個複雜的非標準表單小部件,或者文字輸入是否可以。如果可能的話,不要使用 JavaScript 生成你所有的 HTML 內容。

保持非侵入性

在建立內容時,你應該牢記非侵入式 JavaScript 的理念。非侵入式 JavaScript 的理念是,它應該儘可能地用於增強功能,而不是完全構建功能——基本功能理想情況下應該在沒有 JavaScript 的情況下工作,儘管我們認識到這並不總是一個選項。但是,再次強調,很大程度上是儘可能地使用內建的瀏覽器功能。

非侵入式 JavaScript 的一些很好的示例包括

  • 提供客戶端表單驗證,在使用者提交表單時快速提醒他們表單輸入的問題,而無需等待伺服器檢查資料。如果它不可用,表單仍然可以工作,但驗證可能會比較慢。
  • 為 HTML <video> 提供自定義控制元件,使其可供僅使用鍵盤的使用者訪問,以及一個指向影片的直接連結,以便在 JavaScript 不可用時訪問影片(在大多數瀏覽器中,預設的 <video> 瀏覽器控制元件無法透過鍵盤訪問)。

例如,我們編寫了一個快速簡陋的客戶端表單驗證示例——請參閱 form-validation.html(還可以 檢視演示)。在這裡,你會看到一個簡單的表單;當嘗試提交表單時,如果一個或兩個欄位為空,提交將失敗,並會出現一個錯誤訊息框,告訴你哪裡出了問題。

這種型別的表單驗證是非侵入式的——即使沒有 JavaScript,你仍然可以使用表單,任何合理的表單實現都將擁有伺服器端驗證,因為惡意使用者很容易繞過客戶端驗證(例如,在瀏覽器中關閉 JavaScript)。客戶端驗證仍然非常有用,因為它可以報告錯誤——使用者可以立即知道他們犯了什麼錯誤,而不必等待往返伺服器和頁面重新載入。這是一個明顯的可用性優勢。

注意:伺服器端驗證在此簡單演示中尚未實現。

我們還使這個表單驗證變得非常無障礙。我們使用了 <label> 元素,確保表單標籤明確地與它們的輸入元素相關聯,以便螢幕閱讀器可以將它們與輸入元素一起讀出。

html
<label for="name">Enter your name:</label>
<input type="text" name="name" id="name" />

我們只在提交表單時進行驗證——這樣做的目的是為了避免過快地更新 UI,以免造成螢幕閱讀器(以及其他使用者)的混淆。

js
form.onsubmit = validate;

function validate(e) {
  errorList.textContent = "";
  for (let i = 0; i < formItems.length; i++) {
    const testItem = formItems[i];
    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 中。

js
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 屬性來幫助解決由內容區域不斷更新而沒有頁面重新載入(螢幕閱讀器預設情況下不會拾取或提醒使用者)造成的無障礙性問題。

html
<div class="errors" role="alert" aria-relevant="all">
  <ul></ul>
</div>

我們將在下一篇文章中解釋這些屬性,該文章將更詳細地介紹 WAI-ARIA

注意:你們中有些人可能會想到,HTML 表單有內建的驗證機制,例如 requiredmin/minlengthmax/maxlength 屬性(有關更多資訊,請參閱 <input> 元素參考)。我們在演示中沒有使用這些屬性,因為它們的跨瀏覽器支援存在問題(例如,IE10 及更高版本才支援)。

注意:WebAIM 的 可用且無障礙的表單驗證和錯誤恢復 提供了一些關於無障礙表單驗證的有用資訊。

其他 JavaScript 無障礙性問題

在實現 JavaScript 並考慮無障礙性時,還有其他一些需要注意的事項。我們會在發現這些問題時新增更多內容。

特定於滑鼠的事件

你可能知道,大多數使用者互動都是使用客戶端 JavaScript 透過事件處理程式實現的,事件處理程式允許我們根據發生的特定事件來執行函式。某些事件可能存在無障礙性問題。你會遇到一個主要的示例,即特定於滑鼠的事件,如 mouseovermouseoutdblclick 等。響應這些事件執行的功能無法透過其他機制(如鍵盤控制)訪問。

為了緩解這些問題,你應該用可以透過其他方式啟用的類似事件(即所謂的裝置無關事件處理程式)來補充這些事件——focusblur 將為鍵盤使用者提供無障礙性。

讓我們看一個突出顯示何時可能有用處的示例。也許我們想要提供一個縮圖,當滑鼠懸停在上面或獲得焦點時,顯示該影像的較大版本(就像你在電子商務產品目錄中看到的那樣)。

我們製作了一個非常簡單的示例,你可以在 mouse-and-keyboard-events.html 中找到(還可以檢視 原始碼)。程式碼包含兩個函式,用於顯示和隱藏放大的影像;這兩個函式由以下行執行,將它們設定為事件處理程式

js
imgThumb.onmouseover = showImg;
imgThumb.onmouseout = hideImg;

imgThumb.onfocus = showImg;
imgThumb.onblur = hideImg;

前兩行分別在滑鼠指標懸停在縮圖上和停止懸停在縮圖上時執行函式。但這不會讓我們透過鍵盤訪問放大檢視——為了實現這一點,我們添加了最後兩行,這兩行分別在影像獲得焦點和失去焦點(焦點停止)時執行函式。這可以透過將 Tab 鍵移到影像上來完成,因為我們已在影像上添加了 tabindex="0"

click 事件很有意思——它聽起來像是依賴於滑鼠的,但大多數瀏覽器會在按下連結或表單元素的 Enter/Return 鍵(已獲得焦點)或在觸控式螢幕裝置上點選此類元素後,啟用 onclick 事件處理程式。但是,預設情況下,如果你允許一個非預設可聚焦事件獲得焦點,使用 tabindex,則它不會起作用——在這種情況下,你需要專門檢測該鍵何時被按下(請參閱 重新構建鍵盤無障礙性)。

測試您的技能!

你已經閱讀完這篇文章,但你還記得最重要的資訊嗎?在繼續之前,你可以找到一些進一步的測試,以驗證你是否保留了這些資訊——請參閱 測試你的技能:CSS 和 JavaScript 無障礙性

摘要

我們希望這篇文章能讓你對網頁上使用 CSS 和 JavaScript 時的無障礙性問題有一個很好的瞭解。

接下來,WAI-ARIA!