DEV Community

Cole Walker
Cole Walker

Posted on • Edited on

Easy Accessibility: <button> vs <a>

Hello, I'm back with another quick accessibility tip! This time, it's a bit of HTML semantics.

A lot of times, front-end developers will use < a > and < button > interchangeably. The truth is, this is completely wrong! Using the correct tag is very important for a11y, since the expected functionality is incredibly different between the two, and screen readers will give different hints to users based on the type of tag. Additionally, I find that using proper semantic HTML makes your code much easier to read as well!

When do I use the < a > tag?

The < a > tag should be used for links, and links only! If it takes you to a different page or scrolls you to a different part of the page, it's an < a > tag.

A good rule of thumb: if you aren't using a meaningful href attribute, use a button!

When do I use the < button > tag?

The < button > tag should be used for an element which will execute a script when it is clicked. A good example is having a < button > which will open a modal on click.

This could obviously be a billion things, but often times, developers will use < a > tags when they should use < button >s since they want it to be styled like one. However, the< button > element can very easily be styled to look exactly like an < a > tag, so there is no excuse for using it where you shouldn't be!

Top comments (10)

Collapse
 
hozefaj profile image
Hozefa • Edited

One good way I have seen to prevent us from making this error is using eslint a11y rules for anchors.

Over the course of time, I have learned so many subtle differences in the usage of a vs button because of it.

Collapse
 
harryadney profile image
Martin Dimmock

Dumb question time: is that for React pages only?

Cheers.

Collapse
 
hozefaj profile image
Hozefa

There are parsers for other frameworks like vue or even typescript. So short answer is NO. eslint should work on most modern frameworks.

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt

What do think about clickable <span> or <div>? Maybe it is supposedly bad?

However, the <button> element can very easily be styled to look exactly like an <a> tag

What is the fastest / best way to do this consistently, regardless of User Agent Stylesheet?

Collapse
 
colewalker profile image
Cole Walker

Clickable < span >s or < div >s are bad because they are "meaningless" tags. There is no indication to the user agent that they do anything, they're just meant to be containers, therefore without using the proper aria attributes, screen readers and other accessibility technology will not be able to tell their users that the element is clickable. This also goes for assigning scripts to any other non-button element. The way of making a < div > or < span > (or any other element) "look like" a button to the user agent is by setting aria-role="button". This will tell screen readers to read that element as a button!

I found a button style reset here, which will work for all User Agents. That being said, setting border=none, padding=0, and margin=0, makes it basically a blank slate. Additionally, I found a nice CSS Tricks article which sums up all of the ways of doing it better than I could.

Collapse
 
floede profile image
Janus Hasseriis • Edited

I don't think the distinction between a and button is all that difficult when given base level examples. (Although many sites and developers still get it wrong, or use clickable divs)

I'm way more interested in discussing how we semantically construct more complex elements.
Like the ubiquitous "card".
A box with an image, a header, some text. Maybe more.
If I click anywhere within the card, a new page opens.

Is the whole card just placed inside an a? That doesn't feel quite right.

Collapse
 
louisreed profile image
Louis A. Reed Jr.

The anchor tag is a request for a resource. The resource could be a page, a location within a page or some other type of file (image, video, etc). A button tag should be used for all other types of interaction which are not performed by other native HTML interactive elements (checkbox, select, radio, etc). Anchor tags must function when they have keyboard focus and the user presses the ENTER key. Button tags must function when they have keyboard focus and the user presses the ENTER key or the SPACEBAR key. The problem with using divider tags or span tags for either of these elements is that these elements are not part of the natural tab sequence and do not by default receive keyboard focus or visible focus indication, and also by default these elements do not have the necessary event triggers associated with them.

Collapse
 
dansilcox profile image
Dan Silcox

Definitely guilty of this mixup in the past - thanks for the tip and I will put it into practice right away!

Collapse
 
colewalker profile image
Cole Walker

I think we all have been! I have a few websites out there which are embarrassing to look back at now!

Collapse
 
dansilcox profile image
Dan Silcox

No doubt! The worst is when you are looking at some code saying to yourself ‘who wrote this garbage!’ Only to do a ‘git blame’ and realise... oh it was me... 😂🤦‍♂️