The button role should be used for clickable elements that trigger a response when activated by the user. On its own, role="button"
can make any element (e.g. <p>
, <span>
or <div>
) appear as a button control to a screen reader. Additionally, this role can be used in combination with the aria-pressed
attribute to create toggle buttons.
<button>
, <input type="button" />
, <input type="submit" />, <input type="reset" />
and <input type="image" />
) rather than the button
role, as native HTML buttons are more widely supported by older user agents and assistive technology. Native HTML buttons also support keyboard and focus requirements by default, without need for additional customization. Keyboard and focus
Buttons are interactive controls and thus focusable. If the button
role is added to an element that is not focusable by itself (such as <span>
, <div>
or <p>
) then, the tabindex
attributes have to be used to make the button focusable.
Buttons can be operated by both mouse users as well as keyboard users. For native HTML <button>
elements, the button's onclick
event will fire both for mouse clicks and when pressing Space or Enter, while the button has focus. But if another tag is used to create a custom button, the onclick
event will only fire when clicked by the mouse cursor, even if role="button"
is used. Because of this, the developer will have to add a separate key event handler to the element so that the button can be triggered when the Space or Enter key is pressed.
Warning: Be careful when marking up links with the button role. Buttons are expected to be triggered using the Space or Enter key, while links are expected to be triggered using the Enter key. In other words, when links are used to behave like buttons, adding role="button"
alone is not sufficient. It will also be necessary to add a key event handler that listens for the Space key in order to be consistent with native buttons.
Toggle buttons
An advantage of using role="button" is that it allows the creation of toggle buttons. A toggle button can have two states: pressed and not pressed. Whether a button is a toggle button or not can be indicated with the aria-pressed
attribute in addition to the button
role:
- If
aria-pressed
is not used the button is not a toggle buttton. - If
aria-pressed="false"
is used the button is a toggle button that is currently not pressed. - If
is used the button is a toggle button that is currently pressed.aria-pressed="true"
- if
aria-pressed="mixed"
is used, the button is considered to be partially pressed.
Labeling buttons
Buttons should always have an accessible name. For most buttons, this name will be the same as the text inside the button. In some cases, for example for icon buttons, the accessible name can be provided through an aria-label
or aria-labelledby
attribute.
Possible effects on user agents and assistive technology
When the button
role is used, user agents should expose the element as a button control in the operating system's accessibility API. Screen readers should announce the element as a button and describe its accessible name. Speech recognition software should allow the button to be activated by saying "click" followed by the button's accessible name.
Examples
ARIA Basic Button
In the snippet below, a span element has been given the button
role. Because a <span>
element is used, the tabindex
attribute is required to make the button focusable and part of the tab order. Note that this snippet implies that CSS styles are provided to make the <span>
element look like a button and that handleBtnClick
and handleBtnKeyPress
are event handlers that perform the button's action when clicked and when the Space or Enter key are pressed.
<span role="button" tabindex="0" onclick="handleBtnClick()" onKeyPress="handleBtnKeyPress()">Save</span>
ARIA Toggle Button
In this snippet a <span>
element is converted to a toggle button using the button
role and the aria-pressed
attribute. When the button is activated, the aria-pressed
value keeps on switching between true
and false.
HTML
<button type="button" aria-pressed="false" onclick="handleBtnClick(event)"> Native button toggle </button> <span role="button" tabindex="0" aria-pressed="false" onclick="handleBtnClick(event)" onKeyPress="handleBtnKeyPress(event)"> Span button toggle </span>
CSS
button, [role="button"] { padding: 3px; border: 1px solid #CCC; } button[aria-pressed="true"], [role="button"][aria-pressed="true"] { border: 2px solid #000; }
JavaScript
function handleBtnClick(event) { toggleButton(event.target); } function handleBtnKeyPress(event) { // Check to see if space or enter were pressed if (event.keyCode === 32 || event.keyCode === 13) { // Prevent the default action to stop scrolling when space is pressed event.preventDefault(); toggleButton(event.target); } } function toggleButton(element) { // Check to see if the button is pressed var pressed = (element.getAttribute("aria-pressed") === "true"); // Change aria-pressed to the opposite state element.setAttribute("aria-pressed", !pressed); }