Accessible Buttons

A Button is an interactive element that triggers an action on a webpage or submits a form. The <button> tag has been available for a long time and developers should utilize it for this specific purpose.

This may seem obvious to many developers. Unfortunately there is a lot of code out there that uses <a> tags to do the work of a <button>. This is problematic from an accessibility standpoint because those relying on screen readers may mistakenly assume that clicking it will redirect them to another page. When I review code like this, it makes me sad. If you do this in a new project, think about how sad I will be, and change your ways.

This page covers how to make buttons in three ways. Review all scenarios and choose the one that fits your requirements the best, but make sure to take into account the warnings provided before making your final decision.

An HTML Button.

This is the best solution to use, especially when building from scratch.

The most bulletproof way to make a button. It "just works" for everyone.

The following is a <button> tag with a <label> tag describing what it is for.

Code Walkthrough of the Above Example

Below is the HTML of the above example. Use the dropdown to highlight each of the individual steps that makes the example accessible.

☜ Scroll to read full source ☞

                    
                

A link with the role of button

If you already are using a component similar to this in existing work that is not accessible, go to the developer walkthrough of this section to see how we made our implementation accessible.

I can't tell you how many times I have seen buttons incorrectly marked up as links on a project. When dealing with older projects where it would be time-consuming to refactor the existing functionality and convert these "pseudo-buttons" into proper <button> tags, it might be more practical to add the ARIA role="button" to the existing <a> tags. If you decide to do this, you should first review all the steps below and see what would entail more work: refactoring the code to use actual HTML buttons, or adding the extra JavaScript to the codebase to ensure the "imitation buttons" are accessible.

Submit

Code Walkthrough of the Above Example

Below is the HTML of the above example. Use the dropdown to highlight each of the individual steps that makes the example accessible.

☜ Scroll to read full source ☞

                    
                

A DIV with a role of button

This works, but For the Love of God and All That is Holy, don't do this.

There have been a few projects, particularly ones developed using React and Angular for some reason, where I have observed developers creating buttons using <div> tags.

This hurts my brain. It goes against the ideas of semantic HTML and it makes Tim Berners-Lee cry. Do you really want to make the Father of the Web cry? What kind of monster are you?

If you have an existing project that has code built this way, read the steps below and determine if it would be less work to do the following instead of using real HTML <button> tags.

Submit

Code Walkthrough of the Above Example

Below is the HTML of the above example. Use the dropdown to highlight each of the individual steps that makes the example accessible.

☜ Scroll to read full source ☞

                    
                

Disabled HTML Button.

There are two ways of making a button disabled.

  1. Use the disabled attribute. This prevents click events from being fired. It also removes the button from the keyboard tabbing order, which makes it harder for screen reader users to know that the disabled button even exists.
  2. Use the aria-disabled="true" attribute. This doesn't remove the button from the keyboard tabbing order. It also doesn't prevents click events from being fired except for Chrome on Google Android with Talkback on. (Thanks to Noel Tibbles for pointing this out).

The ideal solution would be to use the aria-disabled="true" attribute, while using JavaScript to prevent the click event from performing an action. This allows the button to be accessible by screen reader users, while still notifying them that it is disabled.

The following button is disabled with the disabled attribute

The following button is disabled with aria-disabled="true"

The following button is disabled with aria-disabled="true" and JavaScript