Button (<button>)
When To Use
- To create an interactive element, with which a user can start an action. 1
Rules
- Descendants are presentational. Therefore don‘t put semantic elements inside this element, since they are not accessible to accessibility APIs. 2
- Buttons should always have an accessible name. This can be achieved in following ways: 2
- Buttons with visible text. 4
- If the button has text and an icon consider hiding the icon if an icon label would be redundant via aria-hidden="true". 4
- If the button only consists of an icon without visible text choose one of the following options:
- hide the image via aria-hidden="true" and add an aria-label or aria-labelledby on the button. 4
- add text inside the button and hide it visually through css. 4
- if the image is an <img> element use <img alt="alt text">. 4
- if the image is a <svg> element use <svg role="img" aria-labelledby="titleID"> with a <title id="titleID"> element inside of it. 5 4
- Adding aria-pressed (which needs to be set to ‘true‘ or ‘false‘) to an element with a role of button turns the button into a toggle button. 3
- In this case, don‘t change the label if the state changes. 3
- While it is strictly speaking accessible to use the disabled attribute on buttons its not very usable. 6
- Disabled buttons dont give the user feedback why they are disabled. Disabled buttons get removed from the tab index, making the context harder to understand. And as soon as a button is disabled it looses focus, which is unexpected for users. 7 6
- A better way is to not disabled buttons, but to show a error message, when the button is pressed, to give the user feedback. 6
- When you need to disable a button use aria-disabled. Using this, the button does not loose focus and it stays in the tab index. But you need to make sure that the button actually does nothing while disabled, via JavaScript. 6
- You may give Assistive Technology users the same feedback you give your visual users. For example, when displaying a loading spinner in the button to visually give feedback for a loading state after pressing the button, you could change the accessible text of the button to "loading".