WAI-ARIA 基礎

承接上一篇文章,有時,製作涉及非語義化 HTML 和動態 JavaScript 更新內容的複雜 UI 控制元件可能會很困難。WAI-ARIA 是一種可以幫助解決此類問題的技術,它透過新增瀏覽器和輔助技術可以識別和使用的進一步語義,讓使用者瞭解正在發生的事情。在這裡,我們將展示如何以基本方式使用它來提高可訪問性。

預備知識 熟悉 HTMLCSS 以及本模組前面課程中教授的可訪問性最佳實踐。
學習成果
  • WAI-ARIA 的目的——為非語義化的 HTML 提供語義,以便輔助技術使用者能夠理解呈現給他們的介面。
  • 基本語法——角色、屬性和狀態。
  • 地標和路標。
  • 增強鍵盤可訪問性。
  • 透過即時區域宣佈動態內容更新。

什麼是 WAI-ARIA?

讓我們首先了解 WAI-ARIA 是什麼,以及它能為我們做什麼。

一系列全新的問題

隨著 Web 應用程式變得越來越複雜和動態,一系列新的可訪問性功能和問題開始出現。

例如,HTML 引入了許多語義元素來定義常見的頁面功能(<nav><footer> 等)。在這些元素可用之前,開發人員會使用帶有 ID 或類的 <div>,例如 <div class="nav">,但這帶來了問題,因為無法透過程式設計方式輕鬆找到特定的頁面功能,例如主導航。

最初的解決方案是在頁面頂部新增一個或多個隱藏連結,以連結到導航(或其他內容),例如

html
<a href="#hidden" class="hidden">Skip to navigation</a>

但這仍然不是很精確,並且只能在螢幕閱讀器從頁面頂部讀取時使用。

另一個例子是,應用程式開始出現複雜的控制元件,例如用於選擇日期的日期選擇器、用於選擇值的滑塊等。HTML 提供了特殊的輸入型別來呈現此類控制元件

html
<input type="date" /> <input type="range" />

這些控制元件最初支援不佳,而且對其進行樣式設定過去和現在在較小程度上仍然很困難,這導致設計人員和開發人員選擇自定義解決方案。一些開發人員沒有使用這些原生功能,而是依賴 JavaScript 庫,這些庫將此類控制元件生成為一系列巢狀的 <div>,然後使用 CSS 進行樣式設定並使用 JavaScript 進行控制。

這裡的問題是它們在視覺上是有效的,但螢幕閱讀器完全無法理解它們是什麼,並且它們的使用者只被告知他們看到的是一堆沒有任何語義來描述它們含義的元素。

WAI-ARIA 登場

WAI-ARIA(Web 可訪問性倡議 - 可訪問富網際網路應用)是 W3C 編寫的規範,定義了一組可應用於元素的額外 HTML 屬性,以提供額外的語義並改進可訪問性(在可訪問性不足的地方)。規範中定義了三個主要功能

角色

這些定義了元素的性質或功能。其中許多是所謂的地標角色,它們在很大程度上覆制了結構元素的語義值,例如 role="navigation"<nav>)、role="banner"(文件 <header>)、role="complementary"<aside>)或 role="search"<search>)。其他一些角色描述了沒有與這些角色匹配的元素的頁面結構,例如 role="tablist"role="tabpanel",這些在 UI 中很常見。

屬性

這些定義了元素的屬性,可用於賦予它們額外的含義或語義。例如,aria-required="true" 指定表單輸入需要填寫才能有效,而 aria-labelledby="label" 允許您在元素上放置一個 ID,然後將其引用為頁面上任何其他元素的標籤,包括多個元素,這是使用 <label for="input"> 無法實現的。例如,您可以使用 aria-labelledby 來指定包含在 <div> 中的關鍵描述是多個表格單元格的標籤,或者您可以將其用作影像 alt 文字的替代方案——將頁面上現有資訊指定為影像的 alt 文字,而不是必須在 alt 屬性中重複。您可以在文字替代方案中看到一個示例。

狀態

定義元素當前條件的特殊屬性,例如 aria-disabled="true",它向螢幕閱讀器指定表單輸入當前已停用。狀態與屬性不同,屬性在應用程式的生命週期中不會改變,而狀態可以改變,通常透過 JavaScript 以程式設計方式改變。

關於 WAI-ARIA 屬性的重要一點是,它們除了瀏覽器可訪問性 API(螢幕閱讀器從中獲取資訊)公開的資訊外,不會影響網頁的任何內容。WAI-ARIA 不影響網頁結構、DOM 等,儘管這些屬性對於透過 CSS 選擇元素很有用。

注意:您可以在 WAI-ARIA 規範中找到所有 ARIA 角色及其用途的有用列表,其中包含指向更多資訊的連結——請參閱角色定義——在本站點上——請參閱ARIA 角色

該規範還包含所有屬性和狀態的列表,其中包含指向更多資訊的連結——請參閱狀態和屬性定義(所有 aria-* 屬性)

WAI-ARIA 在哪裡受支援?

這不是一個容易回答的問題。很難找到一個確鑿的資源來說明 WAI-ARIA 的哪些功能受支援以及在哪裡受支援,因為

  1. WAI-ARIA 規範中有很多功能。
  2. 需要考慮作業系統、瀏覽器和螢幕閱讀器的許多組合。

最後一點是關鍵——首先要使用螢幕閱讀器,您的作業系統需要執行具有必要可訪問性 API 的瀏覽器,以公開螢幕閱讀器完成其工作所需的資訊。大多數流行的作業系統都有一兩個瀏覽器可以與螢幕閱讀器配合使用。Paciello Group 有一篇相當新的文章提供了這方面的資料——請參閱粗略指南:瀏覽器、作業系統和螢幕閱讀器支援更新

接下來,您需要擔心相關瀏覽器是否支援 ARIA 功能並透過其 API 公開它們,以及螢幕閱讀器是否識別該資訊並以有用的方式呈現給其使用者。

  1. 瀏覽器支援幾乎是普遍的。
  2. 螢幕閱讀器對 ARIA 功能的支援尚未達到這個水平,但最流行的螢幕閱讀器正在逐漸實現。您可以透過檢視 Powermapper 的WAI-ARIA 螢幕閱讀器相容性文章來了解支援級別。

在本文中,我們不會嘗試涵蓋所有 WAI-ARIA 功能及其確切的支援細節。相反,我們將涵蓋您需要了解的最關鍵的 WAI-ARIA 功能;如果我們沒有提及任何支援細節,您可以假定該功能得到良好支援。我們將明確提及任何例外情況。

注意:一些 JavaScript 庫支援 WAI-ARIA,這意味著當它們生成複雜的表單控制元件等 UI 功能時,它們會新增 ARIA 屬性以提高這些功能的可訪問性。如果您正在尋找用於快速 UI 開發的第三方 JavaScript 解決方案,則在做出選擇時,您絕對應該將 UI 小部件的可訪問性視為一個重要因素。很好的例子是 jQuery UI(參見關於 jQuery UI:深度可訪問性支援)、ExtJSDojo/Dijit

何時應該使用 WAI-ARIA?

我們之前討論了一些促使 WAI-ARIA 建立的問題,但本質上,WAI-ARIA 在四個主要領域很有用

路標/地標

ARIA 的 role 屬性值可以充當地標,它們可以複製 HTML 元素的語義(例如 <nav>),或者超越 HTML 語義,為不同的功能區域提供路標,例如 searchtablisttablistbox 等。

動態內容更新

螢幕閱讀器通常難以報告不斷變化的內容;使用 ARIA,我們可以使用 aria-live 在內容區域動態更新時通知螢幕閱讀器使用者:例如,透過 JavaScript 在頁面中從伺服器獲取新內容並更新 DOM

增強鍵盤可訪問性

有一些內建的 HTML 元素具有原生的鍵盤可訪問性;當其他元素與 JavaScript 一起用於模擬類似互動時,鍵盤可訪問性和螢幕閱讀器報告會因此受到影響。在不可避免的情況下,WAI-ARIA 提供了一種方法,允許其他元素接收焦點(使用 tabindex)。

非語義控制元件的可訪問性

當一系列巢狀的 <div> 與 CSS/JavaScript 一起用於建立複雜的 UI 功能,或者原生控制元件透過 JavaScript 大幅增強/改變時,可訪問性可能會受到影響——如果沒有語義或其他線索,螢幕閱讀器使用者將難以弄清楚該功能的作用。在這種情況下,ARIA 可以透過結合使用 buttonlistboxtablist 等角色,以及 aria-requiredaria-posinset 等屬性來提供所需的功能線索。

在下一節中,我們將更詳細地探討前面描述的四個主要領域,並附帶示例。在繼續之前,您應該設定一個螢幕閱讀器測試環境,以便您可以邊學邊測試一些示例。有關更多資訊,請參閱我們關於測試螢幕閱讀器的部分。

您只應在需要時才使用 WAI-ARIA!

使用正確的 HTML 元素會隱式地為您提供所需的角色,並且您應該始終使用原生 HTML 功能來提供螢幕閱讀器所需的語義,以便告知其使用者正在發生什麼。有時這不可能,要麼是因為您對程式碼的控制有限,要麼是因為您正在建立一些複雜且沒有簡單 HTML 元素來實現的內容。在這種情況下,WAI-ARIA 可能是一個有價值的可訪問性增強工具。

但再次強調,僅在必要時才使用它!

此外,請儘量確保您使用各種真實使用者測試您的網站——非殘障人士、使用螢幕閱讀器的人、使用鍵盤導航的人等。他們將比您更好地瞭解網站的運作情況。

路標/地標

WAI-ARIA 為瀏覽器添加了 role 屬性,允許您在需要時為網站上的元素新增額外的語義價值。第一個主要用途是為螢幕閱讀器提供資訊,以便其使用者可以找到常見的頁面元素。此示例具有以下結構

html
<header>
  <h1>Header</h1>

  <!-- Even is it's not mandatory, it's common practice to put the main navigation menu within the main header -->

  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">Team</a></li>
      <li><a href="#">Projects</a></li>
      <li><a href="#">Contact</a></li>
    </ul>

    <!-- A Search form is another common non-linear way to navigate through a website. -->

    <form>
      <input type="search" name="q" placeholder="Search query" />
      <input type="submit" value="Go!" />
    </form>
  </nav>
</header>

<!-- Here is our page's main content -->
<main>
  <!-- It contains an article -->
  <article>
    <h2>Article heading</h2>

    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Donec a diam
      lectus. Set sit amet ipsum mauris. Maecenas congue ligula as quam viverra
      nec consectetur ant hendrerit. Donec et mollis dolor. Praesent et diam
      eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue
      enim, ut porta lorem lacinia consectetur.
    </p>

    <h3>subsection</h3>

    <p>
      Donec ut librero sed accu vehicula ultricies a non tortor. Lorem ipsum
      dolor sit amet, consectetur adipisicing elit. Aenean ut gravida lorem. Ut
      turpis felis, pulvinar a semper sed, adipiscing id dolor.
    </p>
  </article>

  <!-- the aside content can also be nested within the main content -->
  <aside>
    <h2>Related</h2>

    <ul>
      <li><a href="#">Oh I do like to be beside the seaside</a></li>
      <li><a href="#">Oh I do like to be beside the sea</a></li>
      <li><a href="#">Although in the North of England</a></li>
      <li><a href="#">It never stops raining</a></li>
      <li><a href="#">Oh well...</a></li>
    </ul>
  </aside>
</main>

<!-- And here is our main footer that is used across all the pages of our website -->

<footer>
  <p>©Copyright 2050 by nobody. All rights reversed.</p>
</footer>

如果您嘗試在現代瀏覽器中使用螢幕閱讀器測試該示例,您將已經獲得一些有用的資訊。例如,VoiceOver 會為您提供以下資訊

  • <header> 元素上——“橫幅,2 項”(它包含一個標題和 <nav>)。
  • <nav> 元素上——“導航,2 項”(它包含一個列表和一個表單)。
  • <main> 元素上——“主要,2 項”(它包含一篇文章和一個側邊欄)。
  • <aside> 元素上——“補充,2 項”(它包含一個標題和一個列表)。
  • 在搜尋表單輸入上——“搜尋查詢,文字開頭插入”。
  • <footer> 元素上——“頁尾,1 項”。

如果您轉到 VoiceOver 的地標選單(使用 VoiceOver 鍵 + U 訪問,然後使用游標鍵迴圈瀏覽選單選項),您會看到大多數元素都很好地列出,以便可以快速訪問。

Mac's VoiceOver menu for quick accessibility. Landmarks header and landmarks list including banner, navigation, main, and complementary.

然而,我們可以在這裡做得更好。搜尋表單是一個非常重要的地標,人們會想要找到它,但它沒有列在地標選單中,也沒有被視為除實際輸入被識別為搜尋輸入(<input type="search">)之外的顯著地標。

要將表單標記為地標,您可以將其包裝在 <search> 元素中,或者為其提供 ARIA role="search"。一般規則是,儘可能使用 HTML 語義,僅在沒有 HTML 等效項時才使用 ARIA。

html
<header>
  <h1>Header</h1>

  <!-- Even is it's not mandatory, it's common practice to put the main navigation menu within the main header -->

  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">Our team</a></li>
      <li><a href="#">Projects</a></li>
      <li><a href="#">Contact</a></li>
    </ul>

    <!-- A Search form is another common non-linear way to navigate through a website. -->

    <search>
      <form>
        <input
          type="search"
          name="q"
          placeholder="Search query"
          aria-label="Search through site content" />
        <input type="submit" value="Go!" />
      </form>
    </search>
  </nav>
</header>

<!-- Here is our page's main content -->
<main>
  <!-- It contains an article -->
  <article>
    <h2>Article heading</h2>

    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Donec a diam
      lectus. Set sit amet ipsum mauris. Maecenas congue ligula as quam viverra
      nec consectetur ant hendrerit. Donec et mollis dolor. Praesent et diam
      eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue
      enim, ut porta lorem lacinia consectetur.
    </p>

    <h3>subsection</h3>

    <p>
      Donec ut librero sed accu vehicula ultricies a non tortor. Lorem ipsum
      dolor sit amet, consectetur adipisicing elit. Aenean ut gravida lorem. Ut
      turpis felis, pulvinar a semper sed, adipiscing id dolor.
    </p>

    <p>
      Pelientesque auctor nisi id magna consequat sagittis. Curabitur dapibus,
      enim sit amet elit pharetra tincidunt feugiat nist imperdiet. Ut convallis
      libero in urna ultrices accumsan. Donec sed odio eros.
    </p>
  </article>

  <!-- the aside content can also be nested within the main content -->
  <aside>
    <h2>Related</h2>
    <ul>
      <li><a href="#">Oh I do like to be beside the seaside</a></li>
      <li><a href="#">Oh I do like to be beside the sea</a></li>
      <li><a href="#">Although in the North of England</a></li>
      <li><a href="#">It never stops raining</a></li>
      <li><a href="#">Oh well...</a></li>
    </ul>
  </aside>
</main>

<!-- And here is our main footer that is used across all the pages of our website -->

<footer>
  <p>©Copyright 2050 by nobody. All rights reversed.</p>
</footer>

最重要的是,我們使用了語義化 HTML,它賦予了頁面結構意義和角色,而沒有在我們的 HTML 結構中新增不必要的 role 屬性,其結構如下

html
<header>
  <h1>…</h1>
  <nav>
    <ul>
      …
    </ul>
    <search>
      <form>
        <!-- search form -->
      </form>
    </search>
  </nav>
</header>

<main>
  <article>…</article>
  <aside>…</aside>
</main>

<footer>…</footer>

在此示例中,我們還為您提供了一個額外功能——<input> 元素被賦予了屬性 aria-label,它為其提供了一個描述性標籤,即使我們沒有包含 <label> 元素,螢幕閱讀器也會將其讀出。在這些情況下,這非常有用——像這樣的搜尋表單是一個非常常見、易於識別的功能,新增可視標籤會破壞頁面設計。

html
<input
  type="search"
  name="q"
  placeholder="Search query"
  aria-label="Search through site content" />

現在,如果我們使用 VoiceOver 檢視此示例,我們會得到一些改進

  • 搜尋表單在瀏覽頁面和地標選單中都被單獨列出。
  • 當表單輸入被高亮顯示時,會讀出 aria-label 屬性中包含的標籤文字。

如果您需要支援 IE8 等舊版瀏覽器;為此目的包含 ARIA 角色是值得的。如果您的網站由於某種原因僅使用 <div> 構建,那麼您絕對應該包含 ARIA 角色以提供這些急需的語義!

您將在下面看到更多關於這些語義和 ARIA 屬性/屬性的強大功能,特別是在非語義控制元件的可訪問性部分。不過現在,讓我們看看 ARIA 如何幫助進行動態內容更新。

動態內容更新

載入到 DOM 中的內容可以使用螢幕閱讀器輕鬆訪問,從文字內容到附加到影像的替代文字。因此,具有大量文字內容的傳統靜態網站很容易讓有視力障礙的人訪問。

問題是現代 Web 應用程式通常不只是靜態文字——它們通常透過從伺服器獲取新內容(在此示例中,我們使用靜態引用陣列)和更新 DOM 來更新頁面的一部分。這些有時被稱為即時區域

讓我們看一個示例——一個隨機名言生成器

html
<section>
  <h1>Random quote generator</h1>
  <button>Start giving me quotes</button>
  <blockquote>
    <p></p>
  </blockquote>
</section>
js
let quotes = [
  {
    quote:
      "Every child is an artist. The problem is how to remain an artist once he grows up.",
    author: "Pablo Picasso",
  },
  {
    quote:
      "You can never cross the ocean until you have the courage to lose sight of the shore.",
    author: "Christopher Columbus",
  },
  {
    quote:
      "I love deadlines. I love the whooshing noise they make as they go by.",
    author: "Douglas Adams",
  },
];
js
const quotePara = document.querySelector("section p");
const btn = document.querySelector("button");

btn.addEventListener("click", () => {
  function showQuote() {
    let random = Math.floor(Math.random() * quotes.length);
    quotePara.textContent = `${quotes[random].quote} -- ${quotes[random].author}`;
  }

  showQuote();
  btn.disabled = true;
  window.setInterval(showQuote, 5000);
});

這工作正常,但不利於可訪問性——螢幕閱讀器無法檢測到內容更新,因此其使用者將不知道發生了什麼。這是一個相當微不足道的示例,但想象一下,如果您正在建立一個具有大量不斷更新內容的複雜 UI,例如聊天室、策略遊戲 UI 或即時更新的購物車顯示——如果沒有某種方式提醒使用者更新,將無法有效使用該應用程式。

WAI-ARIA 幸運地提供了一種有用的機制來提供這些警報——aria-live 屬性。將此屬性應用於元素會導致螢幕閱讀器讀出更新的內容。內容讀出的緊急程度取決於屬性值

關閉

預設。不應宣佈更新。

有禮

僅當用戶處於空閒狀態時才應宣佈更新。

斷言

應儘快向用戶宣佈更新。

在這裡,我們更新 <blockquote> 開標籤,如下所示

html
<blockquote aria-live="assertive">…</blockquote>

這將導致螢幕閱讀器在內容更新時讀出內容:嘗試測試更新的即時版本

注意:還有一些其他與 aria-live 相關的 ARIA 屬性也值得了解

  • aria-atomic 屬性,當設定為 true 時,告訴螢幕閱讀器將整個元素內容作為一個原子單元讀出,而不僅僅是更新的部分。當只有部分內容正在更新時,這很有用,但您也希望每次內容更改時都讀出標題,以提醒使用者其內容。
  • aria-relevant 屬性對於控制當即時區域更新時讀出哪些內容很有用。例如,您只能讀出內容的新增或刪除。

增強鍵盤可訪問性

正如模組中其他一些地方所討論的,HTML 在可訪問性方面的一個關鍵優勢是按鈕、表單控制元件和連結等功能的內建鍵盤可訪問性。通常,您可以使用 Tab 鍵在控制元件之間移動,使用 Enter/Return 鍵選擇或啟用控制元件,並根據需要偶爾使用其他控制元件(例如,在 <select> 框中,使用上下游標在選項之間移動)。

但是,有時您最終不得不編寫使用非語義元素作為按鈕(或其他型別的控制元件)的程式碼,或者將可聚焦控制元件用於不完全正確的目的。您可能正在嘗試修復您繼承的一些糟糕程式碼,或者您可能正在構建某種需要它的複雜小部件。

在使不可聚焦程式碼可聚焦方面,WAI-ARIA 擴充套件了 tabindex 屬性,新增了一些值

  • tabindex="0"——如上所述,此值允許通常不可製表的元素變得可製表。這是 tabindex 最有用的值。
  • tabindex="-1"——這允許通常不可製表的元素以程式設計方式接收焦點,例如,透過 JavaScript,或作為連結的目標。

我們在 HTML 可訪問性文章中更詳細地討論了這一點並展示了典型的實現——請參閱重新構建鍵盤可訪問性

非語義控制元件的可訪問性

這承接了上一節——當一系列巢狀的 <div> 與 CSS/JavaScript 一起用於建立複雜的 UI 功能,或者原生控制元件透過 JavaScript 大幅增強/改變時,不僅鍵盤可訪問性會受到影響,而且如果缺乏語義或其他線索,螢幕閱讀器使用者將難以弄清楚該功能的作用。在這種情況下,ARIA 可以幫助提供這些缺失的語義。

表單驗證和錯誤警報

首先,讓我們回顧一下我們最初在 CSS 和 JavaScript 可訪問性文章中檢視的表單示例(閱讀保持不突兀以獲取完整回顧)。在本節末尾,我們展示了我們在錯誤訊息框中包含了一些 ARIA 屬性,該錯誤訊息框在您嘗試提交表單時顯示任何驗證錯誤

html
<div class="errors" role="alert" aria-relevant="all">
  <ul></ul>
</div>
  • role="alert" 自動將其應用的元素轉換為即時區域,因此對其的更改會被讀出;它還在語義上將其標識為警報訊息(重要的時間/上下文敏感資訊),並且代表了一種更好、更易於訪問的方式向用戶傳遞警報(像 alert() 呼叫這樣的模態對話方塊存在許多可訪問性問題;請參閱 WebAIM 的彈出視窗)。
  • aria-relevant 值為 all 指示螢幕閱讀器在對錯誤列表進行任何更改時(即新增或刪除錯誤時)讀出錯誤列表的內容。這很有用,因為使用者會想知道還剩下哪些錯誤,而不僅僅是列表中新增或刪除了什麼。

我們可以進一步使用 ARIA,提供更多驗證幫助。例如,如何指示欄位是否必填,以及年齡範圍應該是多少?

  1. 此時,複製我們的 form-validation.htmlvalidation.js 檔案,並將它們儲存在本地目錄中。

  2. 在文字編輯器中開啟它們,並檢視程式碼是如何工作的。

  3. 首先,在開頭的 <form> 標籤上方新增一個段落,如下所示,並在兩個表單 <label> 標籤上標記一個星號。這通常是我們為有視力使用者標記必填欄位的方式。

    html
    <p>Fields marked with an asterisk (*) are required.</p>
    
  4. 這在視覺上是合理的,但對於螢幕閱讀器使用者來說並不容易理解。幸運的是,WAI-ARIA 提供了 aria-required 屬性,為螢幕閱讀器提供提示,告知它們應告訴使用者需要填寫表單輸入。像這樣更新 <input> 元素

    html
    <input type="text" name="name" id="name" aria-required="true" />
    
    <input type="number" name="age" id="age" aria-required="true" />
    
  5. 如果您現在儲存示例並使用螢幕閱讀器進行測試,您應該會聽到類似“輸入您的姓名星號,必填,編輯文字”的聲音。

  6. 如果我們為螢幕閱讀器使用者和有視力使用者提供年齡值應該是什麼範圍的概念,那也可能很有用。這通常以工具提示或佔位符的形式呈現在表單欄位中。WAI-ARIA 確實包含 aria-valueminaria-valuemax 屬性來指定最小值和最大值,並且螢幕閱讀器支援原生 minmax 屬性。另一個得到良好支援的功能是 HTML placeholder 屬性,它可以在未輸入值時在輸入框中顯示一條訊息,並由一些螢幕閱讀器讀出。像這樣更新您的數字輸入

    html
    <label for="age">Your age:</label>
    <input
      type="number"
      name="age"
      id="age"
      placeholder="Enter 1 to 150"
      required
      aria-required="true" />
    

始終為每個輸入包含一個 <label>。雖然某些螢幕閱讀器會宣佈佔位符文字,但大多數不會。為表單控制元件提供可訪問名稱的可接受替代方案包括 aria-labelaria-labelledby。但是,帶有 for 屬性的 <label> 元素是首選方法,因為它為所有使用者(包括滑鼠使用者)提供了可用性。

注意:您可以在 form-validation-updated.html 上即時檢視完成的示例。

WAI-ARIA 還支援一些高階表單標籤技術,超越了經典的 <label> 元素。我們已經討論過使用 aria-label 屬性在不希望標籤對有視力使用者可見的情況下提供標籤(請參閱上文路標/地標部分)。其他一些標籤技術使用其他屬性,例如 aria-labelledby,如果您想將非 <label> 元素指定為標籤,或者使用相同的標籤標記多個表單輸入,以及 aria-describedby,如果您想將其他資訊與表單輸入關聯並使其也被讀出。有關更多詳細資訊,請參閱 WebAIM 的高階表單標籤文章

還有許多其他有用的屬性和狀態,用於指示表單元素的狀態。例如,aria-disabled="true" 可用於指示表單欄位已停用。許多瀏覽器會跳過停用的表單欄位,導致螢幕閱讀器不讀出它們。在某些情況下,停用的元素會被感知到,因此包含此屬性以告知螢幕閱讀器停用的表單控制元件實際上已停用是一個好主意。

如果輸入的停用狀態可能會改變,那麼指示何時發生以及結果是什麼也是一個好主意。例如,在我們的 form-validation-checkbox-disabled.html 演示中,有一個複選框,當選中時,它會啟用另一個表單輸入以允許輸入更多資訊。我們設定了一個隱藏的即時區域

html
<p class="hidden-alert" aria-live="assertive"></p>

它使用絕對定位從檢視中隱藏。當選中/取消選中此複選框時,我們會更新隱藏即時區域內的文字,以告知螢幕閱讀器使用者選中此複選框的結果是什麼,並更新 aria-disabled 狀態和一些視覺指示器。

js
function toggleMusician(bool) {
  const instrument = formItems[formItems.length - 1];
  if (bool) {
    instrument.input.disabled = false;
    instrument.label.style.color = "black";
    instrument.input.setAttribute("aria-disabled", "false");
    hiddenAlert.textContent =
      "Instruments played field now enabled; use it to tell us what you play.";
  } else {
    instrument.input.disabled = true;
    instrument.label.style.color = "#999999";
    instrument.input.setAttribute("aria-disabled", "true");
    instrument.input.removeAttribute("aria-label");
    hiddenAlert.textContent = "Instruments played field now disabled.";
  }
}

將非語義按鈕描述為按鈕

在本課程中,我們已經多次提到按鈕、連結或表單元素的原生可訪問性(以及使用其他元素偽造這些元素背後的可訪問性問題)(請參閱 HTML 可訪問性文章中的儘可能使用語義 UI 控制元件,以及上面的增強鍵盤可訪問性)。基本上,在許多情況下,您可以使用 tabindex 和一些 JavaScript 輕鬆地重新新增鍵盤可訪問性。

但是螢幕閱讀器呢?它們仍然不會將這些元素視為按鈕。如果我們在螢幕閱讀器中測試我們的 fake-div-buttons.html 示例,我們的假按鈕將以“點選我!組”之類的短語報告,這顯然令人困惑。

我們可以使用 WAI-ARIA 角色來解決這個問題。製作 fake-div-buttons.html 的本地副本,併為每個按鈕 <div> 新增 role="button",例如

html
<div data-message="This is from the first button" tabindex="0" role="button">
  Click me!
</div>

現在,當您使用螢幕閱讀器嘗試此操作時,您將聽到按鈕以“點選我!按鈕”之類的短語報告。雖然這要好得多,但您仍然必須新增使用者期望的所有原生按鈕功能,例如處理 enter 和點選事件,如button 角色文件中所述。

注意:但不要忘記,儘可能使用正確的語義元素總是更好的。如果您想建立一個按鈕,並且可以使用 <button> 元素,那麼您應該使用 <button> 元素!

引導使用者透過複雜的小部件

還有許多其他角色可以將非語義元素結構標識為超出標準 HTML 範圍的常見 UI 功能,例如 comboboxslidertabpaneltree。您可以在 Deque 大學程式碼庫中看到幾個有用的示例,以瞭解如何使此類控制元件具有可訪問性。

您還可以在我們的 WAI-ARIA 角色文件中找到幾個即時示例。例如,請參閱我們的 ARIA: tab 角色示例,其中解釋瞭如何實現可訪問的選項卡式介面。

總結

本文絕沒有涵蓋 WAI-ARIA 中所有可用的內容,但它應該為您提供了足夠的資訊,讓您瞭解如何使用它,並瞭解您將遇到的一些最常見的需要它的模式。

在下一篇文章中,我們將為您提供一些測試,您可以使用它們來檢查您對所有這些資訊的理解和掌握程度。

另見

  • Aria 狀態和屬性:所有 aria-* 屬性
  • WAI-ARIA 角色:ARIA 角色的類別和 MDN 上涵蓋的角色
  • W3C 上的 HTML 中的 ARIA:一個規範,定義了每個 HTML 功能,瀏覽器對其隱式應用的(ARIA)可訪問性語義以及如果需要額外語義,您可以設定的 WAI-ARIA 功能
  • Deque 大學程式碼庫:一個包含非常有用的實用示例的庫,展示瞭如何使用 WAI-ARIA 功能使複雜 UI 控制元件具有可訪問性
  • W3C 上的 WAI-ARIA 創作實踐:W3C 的一份非常詳細的設計模式,解釋瞭如何實現不同型別的複雜 UI 控制元件,同時使用 WAI-ARIA 功能使它們具有可訪問性