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 |
未知规范 |