ARIA:按鈕角色

button 角色用於可點選元素,這些元素在使用者啟用時會觸發響應。新增 role="button" 會告訴螢幕閱讀器該元素是一個按鈕,但不會提供任何按鈕功能。請改用 <button><input> 並設定 type="button"

描述

按鈕角色將元素標識為輔助技術(例如螢幕閱讀器)的按鈕。按鈕是一種用於執行操作的小部件,例如提交表單、開啟對話方塊、取消操作或執行命令(例如插入新記錄或顯示資訊)。新增 role="button" 會告訴輔助技術該元素是一個按鈕,但不會提供任何按鈕功能。請改用 <button><input> 並設定 type="button"

button 角色可以與 aria-pressed 屬性結合使用以 建立切換按鈕

html
<div id="saveChanges" tabindex="0" role="button" aria-pressed="false">Save</div>

以上示例建立了一個可聚焦的按鈕,但需要 JavaScript 和 CSS 來包含按鈕外觀和功能。當使用 <button><input> 並設定 type="button" 元素時,這些功能會預設提供。

html
<button type="button" id="saveChanges">Save</button>

注意:如果使用 role="button" 而不是語義化的 <button><input type="button"> 元素,則需要使元素可聚焦併為 clickkeydown 事件定義事件處理程式。這包括處理 EnterSpace 鍵按下,以處理所有形式的使用者輸入。請參閱 WAI-ARIA 官方示例程式碼

除了普通的按鈕小部件之外,在使用非按鈕元素建立切換按鈕或選單按鈕時,也應包含 role="button"

切換按鈕是一種雙狀態按鈕,可以處於關閉(未按下)或開啟(按下)狀態。aria-pressed 屬性值 truefalse 將按鈕標識為切換按鈕。

選單按鈕是一個控制選單的按鈕,並且具有設定為 menutruearia-haspopup 屬性。

所有後代都是演示性的

某些型別的使用者介面元件在平臺輔助功能 API 中表示時,只能包含文字。輔助功能 API 無法表示包含在 button 中的語義元素。為了解決此限制,瀏覽器會自動將角色 presentation 應用於任何 button 元素的所有後代元素,因為這是一個不支援語義子元素的角色。

例如,考慮以下包含標題的 button 元素。

html
<div role="button"><h3>Title of my button</h3></div>

因為 button 的後代是演示性的,所以以下程式碼等效

html
<div role="button"><h3 role="presentation">Title of my button</h3></div>

從輔助技術使用者的角度來看,標題不存在,因為前面的程式碼片段在 輔助功能樹 中等效於以下內容

html
<div role="button">Title of my button</div>

關聯的 ARIA 角色、狀態和屬性

aria-pressed

aria-pressed 屬性將按鈕定義為切換按鈕。該值描述了按鈕的狀態。這些值包括當按鈕當前未按下時為 aria-pressed="false",當按鈕當前按下時為 aria-pressed="true",以及如果按鈕被認為部分按下時為 aria-pressed="mixed"。如果省略該屬性或將其設定為其預設值 aria-pressed="undefined",則元素不支援被按下。

aria-expanded

如果按鈕控制其他元素的組,則 aria-expanded 狀態指示受控組當前是展開還是摺疊。如果按鈕設定了 aria-expanded="false",則該組當前未展開;如果按鈕設定了 aria-expanded="true",則它當前已展開;如果按鈕設定了 aria-expanded="undefined" 或省略了該屬性,則它不可展開。

基本按鈕

按鈕應始終具有可訪問名稱。對於大多數按鈕,此名稱將與按鈕內部的文字相同,位於開始和結束標籤之間。在某些情況下,例如由圖標表示的按鈕,可訪問名稱可以從 aria-labelaria-labelledby 屬性提供。

切換按鈕

切換按鈕通常有兩種狀態:按下和未按下。對於控制其他元素(例如其他切換按鈕或複選框)且這些元素不都具有相同值的切換按鈕,可以使用第三種混合狀態。除了 `button` 角色(如果元素本身不是原生按鈕元素)之外,還可以使用 aria-pressed 屬性來指示某個元素是否是切換按鈕。

  • 如果未使用 `aria-pressed`,或將其設定為“未定義”狀態,則該按鈕不是切換按鈕。
  • 如果使用 `aria-pressed="false"`,則該按鈕是當前未按下的切換按鈕。
  • 如果使用 `aria-pressed="true"`,則該按鈕是當前按下的切換按鈕。
  • 如果使用 `aria-pressed="mixed"`,則該按鈕被視為部分按下。

例如,音訊播放器上的“靜音”按鈕可以透過將 `aria-pressed` 狀態設定為 true 來指示聲音已靜音。切換按鈕的標籤在狀態發生變化時不應改變。在我們的示例中,標籤保持為“靜音”,螢幕閱讀器會根據 `aria-pressed` 的值讀取“靜音切換按鈕已按下”或“靜音切換按鈕未按下”。如果設計要求按鈕標籤從“靜音”更改為“取消靜音”,則切換按鈕不適用,因此將省略 `aria-pressed` 屬性。

鍵盤互動

功能
Enter 啟用按鈕。
空格 啟用按鈕

在按鈕啟用後,將根據按鈕執行的操作型別設定焦點。例如,如果單擊按鈕開啟對話方塊,則焦點應移至對話方塊。如果按鈕關閉對話方塊,則焦點應返回到開啟對話方塊的按鈕,除非對話方塊上下文執行的功能在邏輯上導致了其他元素。如果按鈕更改了當前上下文,例如音訊檔案的靜音和取消靜音,則焦點通常會保留在按鈕上。

必需的 JavaScript 特性

必需的事件處理程式

滑鼠、觸控和鍵盤使用者都可以操作按鈕。對於原生的 HTML `<button>` 元素,按鈕的 `onclick` 事件會在滑鼠點選以及使用者在按鈕獲得焦點時按下 空格Enter 時觸發。但是,如果使用其他標籤來建立按鈕,即使使用了 `role="button"`,`onclick` 事件也只會滑鼠游標點選時觸發。因此,必須向元素新增單獨的鍵盤事件處理程式,以便在按下 空格Enter 鍵時觸發按鈕。

onclick

處理使用滑鼠點選或觸控事件啟用按鈕時觸發的事件。

onKeyDown

處理使用鍵盤上的 Enter 或空格鍵啟用按鈕時觸發的事件。(注意不要使用 已棄用的 onKeyPress)。

示例

基本按鈕示例

在此示例中,span 元素已賦予 `button` 角色。由於使用了 `<span>` 元素,因此需要 `tabindex` 屬性才能使按鈕可聚焦併成為頁面選項卡順序的一部分。提供的 CSS 樣式用於使 `<span>` 元素看起來像按鈕,並在按鈕獲得焦點時提供視覺提示。

當使用滑鼠點選或 空格Enter 鍵啟用時,`handleBtnClick` 和 `handleBtnKeyDown` 事件處理程式將執行按鈕的操作。在本例中,操作是將新名稱新增到名稱列表中。

嘗試透過在文字框中新增名稱來使用該示例。按鈕將導致該名稱新增到列表中。

HTML

html
<h1>ARIA Button Example</h1>
<ul id="nameList"></ul>
<label for="newName">Enter your Name: </label>
<input type="text" id="newName" />
<span
  role="button"
  tabindex="0"
  onclick="handleCommand(event)"
  onKeyDown="handleCommand(event)"
  >Add Name</span
>

CSS

css
[role="button"] {
  padding: 2px;
  background-color: navy;
  color: white;
  cursor: default;
}
[role="button"]:hover,
[role="button"]:focus,
[role="button"]:active {
  background-color: white;
  color: navy;
}
ul {
  list-style: none;
}

JavaScript

js
function handleCommand(event) {
  // Handles both mouse clicks and keyboard
  // activate with Enter or Space

  // Keypresses other then Enter and Space should not trigger a command
  if (
    event instanceof KeyboardEvent &&
    event.key !== "Enter" &&
    event.key !== " "
  ) {
    return;
  }

  // Get the new name value from the input element
  const newNameInput = document.getElementById("newName");
  const name = newNameInput.value;
  newNameInput.value = ""; // clear the text field
  newNameInput.focus(); // give the text field focus to enable entering and additional name.

  // Don't add blank entries to the list.
  if (name.length > 0) {
    const listItem = document.createElement("li");
    listItem.appendChild(document.createTextNode(name));

    // Add the new name to the list.
    const list = document.getElementById("nameList");
    list.appendChild(listItem);
  }
}

切換按鈕示例

在此程式碼片段中,使用 `button` 角色和 `aria-pressed` 屬性將 <span> 元素轉換為切換按鈕。當啟用按鈕時,`aria-pressed` 值會切換狀態;從 `true` 更改為 `false`,然後再更改回來。

HTML

html
<button
  type="button"
  onclick="handleBtnClick(event)"
  onKeyDown="handleBtnKeyDown(event)">
  Mute Audio
</button>

<span
  role="button"
  tabindex="0"
  aria-pressed="false"
  onclick="handleBtnClick(event)"
  onKeyDown="handleBtnKeyDown(event)">
  Mute Audio
</span>

<audio
  id="audio"
  src="https://soundbible.com/mp3/Tyrannosaurus%20Rex%20Roar-SoundBible.com-807702404.mp3">
  Your browser does not support the `audio` element.
</audio>

CSS

css
button,
[role="button"] {
  padding: 3px;
  border: 2px solid transparent;
}

button:active,
button:focus,
[role="button"][aria-pressed="true"] {
  border: 2px solid #000;
}

JavaScript

js
function handleBtnClick(event) {
  toggleButton(event.target);
}

function handleBtnKeyDown(event) {
  // Check to see if space or enter were pressed
  // "Spacebar" for IE11 support
  if (event.key === " " || event.key === "Enter" || event.key === "Spacebar") {
    // Prevent the default action to stop scrolling when space is pressed
    event.preventDefault();
    toggleButton(event.target);
  }
}

function toggleButton(element) {
  const audio = document.getElementById("audio");

  // Check to see if the button is pressed
  const pressed = element.getAttribute("aria-pressed") === "true";

  // Change aria-pressed to the opposite state
  element.setAttribute("aria-pressed", !pressed);

  // Toggle the play state of the audio file
  if (pressed) {
    audio.pause();
  } else {
    audio.play();
  }
}

結果

無障礙問題

按鈕是互動式控制元件,因此可聚焦。如果將 `button` 角色新增到本身不可聚焦的元素(例如 `<span>`、`<div>` 或 `<p>`),則必須使用 `tabindex` 屬性才能使按鈕可聚焦。

警告:在使用按鈕角色標記連結時要小心。預期按鈕使用 空格Enter 鍵觸發,而連結則預期使用 Enter 鍵觸發。換句話說,當連結用於充當按鈕時,僅新增 `role="button"` 不夠。還需要新增一個偵聽 空格 鍵的鍵盤事件處理程式,以與原生按鈕保持一致。

當使用 `button` 角色時,螢幕閱讀器會將元素宣佈為按鈕,通常會說“點選”,然後是按鈕的可訪問名稱。可訪問名稱要麼是元素的內容,要麼是 `aria-label` 或 `aria-labelledby` 屬性引用的元素的值,或者包括的描述。

最佳實踐

如果連結執行按鈕的操作,則為元素提供 `role="button"` 可以幫助輔助技術使用者瞭解元素的功能。但是,更好的解決方案是調整視覺設計以使其與功能和 ARIA 角色匹配。在可能的情況下,建議使用原生的 HTML 按鈕(`<button>`、`<input type="button">`、`<input type="submit">`、`<input type="reset">` 和 `<input type="image">`),而不是 `button` 角色,因為所有使用者代理和輔助技術都支援原生的 HTML 按鈕,並且預設情況下提供鍵盤和焦點要求,無需額外的自定義。

規範

規範
可訪問的富網際網路應用程式 (WAI-ARIA)
# button
未知規範

另請參閱