Button
A button is a UI widget that is used to trigger an action or event. It is typically used to submit a form, open a dialog, cancel or confirm an action, or perform a CRUD operation.
In most cases, a button should be implemented using semantic HTML button
element but it is also possible to use a non-button
element with the role="button"
attribute.
Role
A button widget must have a role of button. The best way to achieve this is to use the semantic HTML button
element.
If you are using a non-button element, you must add the role="button"
attribute to the element.
1<!-- Better to use the button element -->2↖ <button class="button">Do something</button>34<!-- If not using the button element, add `role="button"` -->5↘ <div class="button" role="button">Do something</div>
Button name
A button must have an accessible name. The accessible name is the text that is read by screen readers to describe the element. Buttons support name from content, so its accessible name could be given from a direct text node child, an image with an alternative text, or even multiple children elements with an accessible name. Othewise, the accessible name can be provided in a couple of ways:
1<!-- The img tag's alt attribute constitutes the button's accessible name -->2<button>3 <img src="./do-something.png" alt="Do something" />4</button>56<!-- Button gets its accessible name from the aria-label attribute -->7<button aria-label="Do something">8 <img src="./do-something.png" aria-hidden="true" />9</button>
Focus sequence
A button must be focusable unless it is disabled. This is important for keyboard users who need to be able to navigate the button.
Semantic HTML buttons are always focusable when not disabled. Non-semantic buttons can be made focusable by adding the tabindex="0"
attribute to the button element.
1<div class="button" role="button" tabindex="0">Do something</div>
Disabled buttons
A semantic HTML button can be disabled by adding the disabled
attribute to the button element. A disabled button is not focusable.
Non-semantic buttons can be disabled by adding the aria-disabled="true"
attribute to the button element.
In that case the developer may choose to make the button focusable or not. It should not be possible to activate the button when disabled,
see Keyboard activation. The aria-disabled
attribute should not be used on a semantic HTML button.
1<!-- Disabled non-semantic HTML button -->2<div class="button" role="button" aria-disabled="true">Do something</div>34<!-- Disabled non-semantic HTML button that is focusable -->5<div class="button" role="button" aria-disabled="true" tabindex="0">Do something</div>67<!-- Semantic HTML button should not use aria-disabled -->8✓ <button disabled>Do something</button>9✗ <button aria-disabled="true">Do something</button>
ARIA owns
If the button should contain elements that cannot be implemented as descendants of the button,
the aria-owns
attribute can be used to indicate that the button owns the elements.
However, since the aria-owns
attribute is not supported by some assistive technologies,
it is best practice to avoid it. If it must be used, the aria-owns
attribute should be set
on the button and should point to the IDs of the owned elements.
Forbidden interactive children
A button must not contain any interactive children such as links or buttons. Such children would be inaccessible to screen reader users since they will be excluded from the accessibility tree.
Keyboard activation
Unless disabled, button must be activated by pressing the enter key or the space key. This is important for keyboard users. Semantic HTML buttons have built-in keyboard activation. Non-semantic buttons can be activated by adding an event handler.
1// Non-semantic HTML button is activated by adding an event handler2const button = document.getElementById('my-button');3button.addEventListener('click', doSomething);4button.addEventListener('keydown', (event) => {5 if (event.key === 'Enter' || event.key === ' ') {6 doSomething();7 event.preventDefault();8 }9});