Eric Niquette UI, UX, Accessibility

Introduction

In my experience, developers often use anchors and buttons interchangeably for all sorts of tasks, like opening menus and modals, redirecting users, or even submitting forms.

For most users, this usually goes unnoticed and has little to no impact. But for people relying on assistive technologies, it makes a big difference. That small bit of semantic context is essential for understanding what action is being taken and what to expect next.

Semantics

Writing semantic HTML means using the right tool for the the job and helping users avoid unexpected interactions with your product. When someone clicks a link, they expect to be redirected. Likewise, pressing a button signals that some kind of action will happen.

I dive deeper into semantic HTML in my article Championing Usability and Accessibility with HTML Semantics, but in short, using the right semantic elements is key to meeting user expectations and creating a more intuitive experience.

Using the anchor element

The anchor element (<a>) is primarily used to link to another location, whether within the same document, a different webpage, or an external site.

However, it shouldn't be used to trigger functions or fire events. A common mistake is using an anchor with an empty fragment (#) tied to an event listener, like in the example below.

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

This function should, instead, use a <button>. However, this isn't a strict rule. Like most guidelines, there are exceptions. One example is a multi-level menu that expands or collapses, where using an anchor as a trigger can make sense.

<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 to link to a resource, an anchor's formatting can also vary depending on the target destination and the protocol being used.

<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>

Using the button element

The <button> is an interactive element that activates when clicked, tapped, or triggered by another action. By itself, it doesn't perform any function. It needs to be connected to a programmed action, like toggling content or opening a modal window.

It's important not to use a button for redirecting users; that's what anchors (<a>) are for.

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

The <button> can also be set to a disabled state, preventing user interaction until certain conditions are met. This feature isn't available for anchors.

One common reason I've seen developers use an anchor instead of a button is the need for it to appear inline and blend in with other links. In these cases, CSS can easily style buttons to match seamlessly.

Using the button input type

The <input type="button"> element is designed for use within forms. Common functions include saving, submitting, clearing inputs, or handling other data-processing tasks.

<form>
  <input type="submit" value="Submit">
  <input type="reset" value="Reset">
</form>

It's best not to use input buttons outside of a form. However, a standard <button> can be used within a form. By default, an unassigned <button> inside a form will automatically submit the form.

<form>
  <button>This button will submit the form</button>
</form>

Accessibility considerations

Assistive technologies like screen readers recognize and announce button and anchor elements differently, which helps set user expectations. For example, most screen readers will announce the following button as: "More information. Button." This cues the user to expect a pop-up, tooltip, or informational window when the button is activated.

<button>More information</button>

In contrast, a screen reader will announce this anchor as: "Link. More information." This signals that clicking the link will redirect the user to another page with additional details.

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

Using the correct element ensures that users relying on assistive technologies have a clear understanding of what action will occur.

Working around limitations with roles

In some situations, you might not be able to swap out an element due to dependencies in scripts, stylesheets, or other restrictions. As a workaround, the role attribute can override an element's default semantic meaning, changing how screen readers interpret it.

For example, this button will be read as a link by screen readers:

<button role="link">

Conversely, this link will be announced as a button:

<a role="button">

However, using the role attribute is generally discouraged and should only be a last resort when no other solution is possible. It's best to use the correct semantic elements to maintain accessibility and clarity.

Activating buttons

Another key difference is how these elements are activated. The <button> element can be triggered using the Enter key or the Spacebar, while the <a> element can only be activated with the Enter key.

Styling an anchor to look like a button might mislead users who expect the Spacebar to work. However, since this practice is so common and there's no perfect semantic alternative, the impact is usually minimal.

Takeaways

Screen readers recognize the difference between anchors and buttons, setting user expectations for how these elements should behave when activated.

  • Buttons are meant to trigger actions or initiate functions.
  • Anchors are primarily for navigation and redirection.
  • Input buttons are designed for form-related tasks.
  • Use the role attribute cautiously and only when necessary.