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

另请参阅