ARIA:按鈕角色
button 角色用於可點選元素,這些元素在使用者啟用時會觸發響應。新增 role="button" 會告訴螢幕閱讀器該元素是一個按鈕,但不會提供任何按鈕功能。請改用 <button> 或 <input> 並設定 type="button"。
描述
按鈕角色將元素標識為輔助技術(例如螢幕閱讀器)的按鈕。按鈕是一種用於執行操作的小部件,例如提交表單、開啟對話方塊、取消操作或執行命令(例如插入新記錄或顯示資訊)。新增 role="button" 會告訴輔助技術該元素是一個按鈕,但不會提供任何按鈕功能。請改用 <button> 或 <input> 並設定 type="button"。
此 button 角色可以與 aria-pressed 屬性結合使用以 建立切換按鈕。
<div id="saveChanges" tabindex="0" role="button" aria-pressed="false">Save</div>
以上示例建立了一個可聚焦的按鈕,但需要 JavaScript 和 CSS 來包含按鈕外觀和功能。當使用 <button> 和 <input> 並設定 type="button" 元素時,這些功能會預設提供。
<button type="button" id="saveChanges">Save</button>
注意:如果使用 role="button" 而不是語義化的 <button> 或 <input type="button"> 元素,則需要使元素可聚焦併為 click 和 keydown 事件定義事件處理程式。這包括處理 Enter 和 Space 鍵按下,以處理所有形式的使用者輸入。請參閱 WAI-ARIA 官方示例程式碼。
除了普通的按鈕小部件之外,在使用非按鈕元素建立切換按鈕或選單按鈕時,也應包含 role="button"。
切換按鈕是一種雙狀態按鈕,可以處於關閉(未按下)或開啟(按下)狀態。aria-pressed 屬性值 true 或 false 將按鈕標識為切換按鈕。
選單按鈕是一個控制選單的按鈕,並且具有設定為 menu 或 true 的 aria-haspopup 屬性。
所有後代都是演示性的
某些型別的使用者介面元件在平臺輔助功能 API 中表示時,只能包含文字。輔助功能 API 無法表示包含在 button 中的語義元素。為了解決此限制,瀏覽器會自動將角色 presentation 應用於任何 button 元素的所有後代元素,因為這是一個不支援語義子元素的角色。
例如,考慮以下包含標題的 button 元素。
<div role="button"><h3>Title of my button</h3></div>
因為 button 的後代是演示性的,所以以下程式碼等效
<div role="button"><h3 role="presentation">Title of my button</h3></div>
從輔助技術使用者的角度來看,標題不存在,因為前面的程式碼片段在 輔助功能樹 中等效於以下內容
<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-label 或 aria-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
<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
[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
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
<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
button,
[role="button"] {
padding: 3px;
border: 2px solid transparent;
}
button:active,
button:focus,
[role="button"][aria-pressed="true"] {
border: 2px solid #000;
}
JavaScript
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 |
| 未知規範 |