Eric Niquette

Heads-up: This article is being migrated to a new format and may be incomplete. Some of the contents, media, and images may be missing or appear incorrectly. Please forgive any issues while I bring it up to par.

Introduction

In my experience, developers tend to use anchors and buttons interchangeably to accomplish a wide range of tasks, from opening menus and modals to redirecting the user and submitting forms.

To the end user this generally goes unnoticed and is nearly imperceivable. The impact to users relying on assistive tools, however, is considerable and that small bit of semantic context is crucial to understanding what action is being performed and what to expect.

Semantic usage

Writing semantic HTML ensures you're using the right tool for the intended task, preventing users from unexpected interactions with your product. When your activates a link, they anticipate a redirection. Similarly, pressing a button sets the expectation for some form of action to be initiated.

Using the proper semantic element is crucial to meeting these user expectations.

Anchors

The anchor element (<a>) is typically utilized as a link to a different location, whether it's within the same document, to another webpage, or an external website.

It should not, however, be used to initiate a function or fire an event. A common error is the usage of an anchor with an empty fragment linked to an event listener, as demonstrated below.

<a href="#" onclick="myFunction();">

This function should be linked to a <button>. This is not an absolute, hard and fast rule, however; as with most rules, there are exceptions to this. One such exception is a multi-level menu that expands or collapses and uses the anchor as a trigger.

<nav>
  <ul>
    <li><a href="">Category 1</a></li>
    <li><a href="">Category 2</a></li>
    <li><a href="" aria-expanded="false">Category 3</a>
      <ul>
        <li><a href="">Item 1</a></li>
        <li><a href="">Item 2</a></li>
      </ul>
    </li>
    <li><a href="">Category 4</a></li>
  </ul>
</nav>

When used for the purpose of linking to a resource, the formatting of an anchor can also vary based on the intended target and protocol.

<a href="#skip">Skip to content</a>
<a href="about.html">About me</a>
<a href="https://www.niquette.ca">Visit my website</a>
<a href="mailto:eric@niquette.ca">Send me an email</a>

Buttons

The generic <button> is an interactive element that actives when clicked, tapped, or otherwise triggered by an action. On its own, it does not perform any function and must be linked to a programmed action such as toggling content or generating a modal window.

It's important to avoid using a button to redirect users. Instead, the anchor should be utilized for this purpose.

<button onclick="myFunction();">Run my function</button>

A common gripe with buttons is that they sometimes have to hide inline with other links. In this event, buttons can be styled to blend in using CSS.

In some conditions, a <button> can also be marked as disabled, preventing user interaction until a certain condition is met. The attribute cannot be applied to an anchor.

Input buttons

The input button element <input type="button"> is intended for use in the context of a form. Examples of form button functions include saving, submitting, and clearing inputs, as well as performing other data-processing functions.

You should not use input buttons outside of a form, but you can use a standard <button> in a form. By default, a <button> with no assignment in a form will trigger that form's submission.

<form>
  <input type="submit" value="Submit">
  <input type="clear" value="Clear">
</form>

Accessibility considerations

Assistive technologies such as screen readers will distinguish between button and anchor elements when encountered. This distinction also sets certain expectations based on the element.

Most screen readers will announce the following button as More information. Button. The expectation is that pressing this button will generate a pop-up, tooltip, or informational window containing more information.

<button>More information</button>

In contrast, readers will announce an anchor as Link. More information. The expectation is that activating the link will redirect the user to another page with more information.

<a href="about.html">More information</a>

Workarounds

In some cases you may be unable to replace an element due to a relationship in a script, stylesheet, or other restriction. As a workaround, the <role> attribute can be used to overwrite and supersede the element's default semantic definition, which will change the way screen readers interpret it.

For example, screen readers will interpret the following button as a link:

<button role="link">

Conversely, the read will interpret the following link as a button:

<a role="button">

Note that using a role is generally a discouraged practice and should only be used if no other options are available. Utilizing proper semantic elements is always preferred.

Activating buttons

One thing to keep in mind is how buttons are activated. The <button> element can be activated using Enter or the Spacebar, while the <a> element can only be activated using the Enter key.

As such, styling an anchor to look like a button has the potential to mislead or confuse your users should they try activating an anchor with the Spacebar. However, given the ubiquity of this practice and the lack of a semantic alternative, the impact should be minimal.

Takeaways

Screen readers differentiate between anchors and buttons and have expectations on their behavior when activated.

  • Buttons are used to trigger actions or initiate functions, but not intended to redirect the user.
  • Anchors are primarily used for redirection and should generally not be used to trigger actions.
  • Input buttons perform actions in a form, like submitting or resetting the data.