{{ariaref}}

The button role should be used for clickable elements that trigger a response when activated by the user. Adding role="button" will make an element appear as a button control to a screen reader. This role can be used in combination with the aria-pressed attribute to create toggle buttons.

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

The above example creates a simple button which is first in the focus order. though <button> or <input> with type="button" should be used for buttons:

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

Note: If using role="button" instead of the semantic <button> or <input type="button" elements, you will need to make the element focusable and have to define event handlers for click and keypress events, including the Enter and Space keys, in order to process the user's input.

Description

The button role identifies an element as a button to screen readers. A button is a widget used to perform actions such as submitting a form, opening a dialog, or cancelling an action, or performing a command such as inserting a new record or displaying information.

A common convention for informing users that a button launches a dialog is to append "…" (ellipsis) to the button label, e.g., "Save as…".

In addition to the ordinary button widget, role="button" should be included when creating a toggle button or menu button using a non button element. A toggle button is a two-state button that can be either off (not pressed) or on (pressed). The aria-pressed attribute values of true or false identify a button as a toggle button. A menu button is a button that controls a menu and has an aria-haspopup property attribute set to either menu or true.

Associated ARIA roles, states, and properties

aria-pressed
Defines the button as a toggle button. The value of aria-pressed describes the state of the button. The values include aria-pressed="false" when a button is not currently pressed, aria-pressed="true" to indicate a button is currently pressed and aria-pressed="mixed" if the button is considered to be partially pressed. If the attribute is omitted or set to its default value of aria-pressed="undefined", the state of the toggle button is undefned.
aria-expanded
If the button controls a grouping of other elements, the aria-expanded state indicates whether a grouping the button element controls is currently expanded or collapsed.  If the button has aria-expanded="false" set, is not currently expanded; If the button has aria-expanded="true" set, it is currently expanded; if the button has aria-expanded="undefined" set or the attribute is ommitted, it is not expandable.

Basic 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.

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 button.
  • If aria-pressed="false" is used the button is a toggle button that is currently not pressed. 
  • If aria-pressed="true" is used the button is a toggle button that is currently pressed.
  • if aria-pressed="mixed" is used, the button is considered to be partially pressed.

As an example, the mute button on an audio player labeled "mute" could indicate that sound is muted by setting the aria-pressed state true. The label of a toggle button should not change when its state changes. In our example the label remains "Mute" with a screen reader reading "Mute toggle button pressed" or "Mute toggle button not pressed" depending on the value of aria-pressed. If the design were to call for the button label to change from "Mute" to "Unmute," a toggle button would not be appropriate, so the the aria-pressed attribute be omitted.

Keyboard interactions

Key Function
Enter Activates the button.
Space Activates the button

Following button activation, focus is set depending on the type of action the button performs. For example, if clicking the button opens a dialog, the focus should move to the dialog. If the button closes a dialog, focus should returns to the button that opened the dialog unless the function performed in the dialog context logically leads to a different element. If the button does alter the current context, then focus typically remains on the button, such as muting and unmuting an audio file.

Required JavaScript Features

Required event handlers

Buttons can be operated by mouse, touch, and keyboard users. For native HTML <button> elements, the button's onclick event fires for mouse clicks and when the user presses Space or Enter while the button has focus. But if another tag is used to create a button, the onclick event only fires when clicked by the mouse cursor, even if role="button" is used. Because of this, separate key event handlers must be added to the element so that the button is be triggered when the Space or Enter key is pressed.

onclick
Handles the event raised when the button is activated using a mouse click or touch event.
onKeyPress
Handles the event raised when the button is activated using the Enter or Space key on the keyboard.

Changing attribute values

aria-pressed

The value of aria-pressed defines the state of a toggle button. This attribute has one of four possible values:

Examples

Basic button example

In this example, 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 page's tab order. The included CSS style is provided to make the <span> element look like a button, and to provide visual cues when the button has focus.

The handleBtnClick and handleBtnKeyPress event handlers perform the button's action when activated using a mouse click or the Space or Enter key. In this case, the action is to add a new name to the list of names.

Try the example by adding a name to the text box. The button will cause the name to be added to a list.

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()" onKeyPress="handleCommand()">Add Name</span>

CSS

[role="button"] {
  padding: 2px;
  background-color: navy;
  color: white;
}
[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

    // Get the new name value from the input element
    let newNameInput = document.getElementById('newName')
    let 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) {
        listItem = document.createElement('li');
        listItem.appendChild(document.createTextNode(name));

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

Toggle button example

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 switches states; changing from true to false and back again.

HTML

<button type="button" onclick="handleBtnClick()" onKeyPress="handleBtnKeyPress()">
  Mute Audio
</button>

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

<audio id="audio" src="https://soundbible.com/mp3/Tyrannosaurus%20Rex%20Roar-SoundBible.com-807702404.mp3">
  Your browser does not support the <code>audio</code> 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 handleBtnKeyPress(event) {
  // Check to see if space or enter were pressed
  if (event.key === " " || event.key === "Enter") {
    // Prevent the default action to stop scrolling when space is pressed
    event.preventDefault();
    toggleButton(event.target);
  }
}

function toggleButton(element) {
  var audio = document.getElementById('audio');
  // 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);
  // toggle the play state of the audio file
  if(pressed) {
     audio.pause();
  } else {
     audio.play();
  }
}

Result

Accessibility concerns

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 attribute has to be used to make the button focusable.

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.

When the button role is used, screen readers announce the element as a button, generally saying "click" followed by the button's accessible name. The accessible name is either the content of the element or the value of an aria label or description, if included.

Best practices

If a link performs the action of a button, giving the element role button helps assistive technology users understand the function of the element. However, a better solution is to adjust the visual design so it matches the function and ARIA role.  Where possible, it is recommended to use native HTML 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 supported by all user agents and assistive technology and provide keyboard and focus requirements by default, without need for additional customization.

Specifications

Specification Status
Accessible Rich Internet Applications (WAI-ARIA) 1.1
The definition of 'button' in that specification.
Recommendation
WAI-ARIA Authoring Practices 1.1
The definition of 'button' in that specification.
Draft

Notes 

ARIA attributes used

Additional resources