How to use the Button Element to improve Accessibility

Reading Time: 8 mins

I’m still here on my ongoing mission of coding accessibly. There is one HTML element that has become a huge stepping stone for me once I learned how to properly use it. That stepping stone was the button element. What? The button element? Why the heck do we need that? Well, if you’ve ever seen code like below, or have written code like this ( points to herself ), then this post is for you:


To be honest, I’d been writing code like the above for years until I realized I was missing opportunities. I know other developers that also write code like the above. Why is this the case? Well, there have been some theories of ignorance and fear being the source. In my case, “semantics” was just one of those words that I didn’t come across in the beginning. I just wanted to build things that I could see. It was like trying to build a cabinet with a box full of tools without truly understanding the tools. Sure I can hammer in all the nails and call it a day. Or I can take the time to see what’s in the toolbox. Maybe I’ll find that a screwdriver might be a better tool for some areas of the end product then a hammer. In the end, using the right tools for the job will result in a higher quality product… or cabinet?

PS: Rachel is no good with analogies…


And semantics – what does that even mean? Take it from a gal who was thrown head first into web development from a fine arts degree and had to google words like “repository” during her first week. There’s so much lingo out there! Even now, as a more experienced dev, it makes my head spin. So let’s go over it all, shall we? How to use the button element and when it’s the right tool for the job.

Okay First – Semantics Really Quick!

I feel so fancy whenever I use this word. Anyway, the gist of semantics are just writing code that stay true to their original purpose. In other words, in HTML5, would you use the <header> element for the footer? Probably not since the element itself makes it obvious what it should be used for – a footer. The same applies to all HTML. There are a lot of elements that have specific uses and therefore shouldn’t be used for just anything. List items should be used for lists, ‘a’ tags for links, paragraph tags for, yep you got it – paragraphs. Of course sometimes it gets confusing – hence why we’re having the button and link discussion now ( imagining that this post is a discussion between you and I ).

Semantics are really important for accessibility because the more you write code the way it was originally intended, the more likely that your code is already accessible out of the box. A good place I like to go to and confirm an element’s original purpose is Mozilla Developer Network. Here’s an example from MDN on the <header> element we mentioned.

What’s so great about buttons?

A lot of what I reference throughout this post is from this gem, “Links are not buttons. Neither are Divs or Spans,” by Karl Groves. The main reason that buttons are awesome is that they’re natively accessible. This means, so long as there isn’t any CSS interfering, I can access a button from my keyboard, voice command, or other methods/devices from a :focus state. If you’re confused as to why we need focus states, check out an earlier post of mine, “An Intro to Accessible Links.

Buttons also have properties and methods that assistive technologies use to relay information to the user through an accessibility API. Using a button means that you can take advantage as a developer of existing properties and methods versus imitating them due to using something else, like a div. This is getting into a more advanced realm for me, but Karl Groves explains more in, “Name, State, Role, and Value: What’s it all about?“. Buttons pretty much have all you need for accessibility from the start.

Why a button and not a link?

Well the first reason is that word I mentioned earlier. Semantics. Depending on what you’re creating via code, it will change whether you use a button or a link.

The two sentences that have become my mental mantra after reading Karl Groves’ post were these:

If it navigates, it is a link. Use link markup with a valid hypertext reference.

If it triggers an action, it is a button. Use a BUTTON element.

I simplified it like this.

If it goes to another page inside or outside the website, then it’s a link. Anything else, it’s most likely going to be a button.

Buttons are for actions. Links are for destinations. Buttons are “Make this happen” and links are “Go to this url”.

Buttons are for triggering modals, revealing hidden content, moving slides within a carousel and so on. Another way to think about it is, if there is no href value, if there is no url that tells it where to go, it’s a button.

If you’re using a link that doesn’t go anywhere, then it’s no longer a link and therefore you should swap it for something that makes sense. Something semantic, there’s that word again, hence the button. If you’ve read the “Links are not buttons…” article already, then you’ll know that links without destinations just confuse assistive technology. This means none of these below should be used on a live website:

The only exception to links that don’t have a full url in the href are anchor links. These are links that jump the user to specific places on the same page or another page. However, to keep these accessible, the wording should help users. The 15 Golden Rules For Developers have a nice tip about using “In this page, or “Jump down to” in the link text. You can also make use of the screen-reader-text class we went over in Accessible Links by the Handbook. This way we can be sure our users know the where the anchors are taking them even with a visual or other physical disability.

So how do we use the button?

When using a button, you should review whether it makes use of the name, state, role, and value attributes. To mimic the chart Karl Groves made:

Name Similar to a person’s unique name, what is the name of this thing?
State What is this thing doing? Implicitly, what else can it do?
Role What type of object is this thing?
Value What value does this thing have? (Typically only form elements have a value)


I was recently told that I didn’t need to use role=”button” on a button since the element itself makes it clear what role it serves. So I’ve stopped using it for now, but it does require more research on my end whether that’s the correct best practice. ( See the conclusion of this for more questions I had.* )

Anyway, once you have those attributes on your buttons, you can use a button for lots of things. You can use buttons inline with links in navigation:

You can use them as the hamburger button on mobile:

You can even use them with icon fonts. I like to use the Chris Coyier’s accessible method in HTML for Icon Font Usage. It combines the use of a screen-reader-text class, data attributes, and aria-hidden to hide icons from screen readers. It’s being used in the hamburger menu example above but here’s what the button looks like by itself:


If you’re worried about writing extra CSS to make the buttons behave similar to the links, I like to use either a modular class I can apply or a Sass mixin. The Sass mixin removes any  browser defaults I don’t want so it’s easier for me to overwrite with my custom styles. It will look something like the below:

I like to remove the background color for things like a navigation so the buttons will behave visually similar with links. I also like to remove any browser set appearances, borders, and padding. If you’re using an auto-prefixer or setting some more global based styles, the above example can be edited to suit your needs.

Conclusion – Buttons are going to change your life!

Making buttons a regular appearance in my code and a habit during my development process took some adjusting at first. Buttons for actions and links for destinations. Now that I have made it a habit, it’s made the most immediate difference in how accessible my code is. However, although I have a solid understanding between whether to use a button or a link, I admit there are still some areas I need to learn more about. A part of me waited to publish this until I could find the answer. Then I decided to publish anyway in the hopes of learning the answer from one of my readers instead. Do we still need to fill in the name attribute of a button if it’s not in a form? Or can name attributes be added to buttons so long as they connect to JS making use of it? As I mentioned earlier as well, do we need to use the role attribute set to a button on an element that’s already clearly a button?

Looking forward to any incoming knowledge. In the meantime, happy button using!

Some Updates since this was last published!

Some time has passed since this post was last published, and as I am continuously learning about accessibility, I’ve adjusted my button practices. I have settled on avoiding the use of a button role when on a button element due to redundancy, and instead, will start adding type=”button” to them instead. This rule applies to action buttons that do not trigger a submit in a form. Adding this type to buttons is a recent change of a11y WP guidelines. The reason being is that some browsers/technologies will assume automatically that a button’s default action is to submit. So defining the type as “button” instead will ensure that doesn’t happen.

Hope this update was helpful and I’ve updated the code examples in the article to reflect the recent change of practices. 🙂

10 thoughts on “How to use the Button Element to improve Accessibility

    • Hi Eric,

      No worries – I saw the html in the email alert I received. From what I know so far, you’re right. The role “button” is reserved for “fake” buttons that aren’t using the button element instead. So it’s to help the technology know something should be treated as a button even if it isn’t. It seems the general consensus though is to just stick with the button element unless one really doesn’t have a choice and can use the role to help them along.

      Thanks for the comment and for stopping by. 🙂

  1. Great article Rachel. Using the proper elements in HTML is hugely important for accessibility. Regarding your questions:

    1) You can omit the role=”button” attribute on the button element. You don’t gain any extra value by having it there.
    2) The HTML5 spec states that the name attribute is optional. If you do provide it, it must have a non-blank value.
    3) I wouldn’t use the name attribute for connecting to JavaScript. That would be better served by the id or class attributes.

    • Hi Shawn, thanks for stopping by!

      And thanks for the answers. I’ve seen button elements still using the role so I guess that’s where I got confused. But if I can still use the element without the role so long as it’s a real button, then it makes sense to me and that’s the path I’ll stay on.

      I’m still a little fuzzy on the name attribute and Javascript however. I originally thought that was it’s purpose due to some W3C writing I’d found:

      It says it’s to be used in forms for use in styling or scripts – but I agree that IDs are generally the better practice. I also wonder if assistive technologies make use of this attribute somehow or if it’s really just an obsolete no purpose attribute. I still add name attributes to buttons out of habit – but what it actually does is still up for exploration. 🙂

      • I suspect when you see buttons with role = button, you’re seeing a developer who’s just learned about ARIA and is really excited to be using it. Which is a fun stage to be in, but can lead to excessive ARIA attributes all over the place 🙂

Leave a Reply