Skip to main content

By Rachel Opperman

How Semantic HTML Improves the Accessibility of a Website

You've no doubt heard the term "accessibility" in relation to a website or web application.

But what does that actually mean? In short, if a website is accessible, it can be operated by anyone, including by those who aren't in the narrow range of "typical users". An accessible website can be accessed and operated by users with an impairment or disability, be it temporary, permanent, physical, or non-physical. As web developers, we need to make sure that the way in which we build our sites and applications doesn't make them difficult, or even impossible, for some of our users to use.

In this post, we'll discuss how using semantic HTML can improve the accessibility of a website and earn easy accessibility wins without much, if any, extra code.

Affordances and semantics

First, it's important to understand that most assistive technologies (e.g., screen readers, braille display, a switch device) rely on programmatically expressed semantics in order to properly interact with a website. To understand that term, we must first understand affordances.

An affordance is any object that provides its user with the opportunity to perform an action. A good example would be a teapot -- its physical design (i.e., the fact that it has a handle) gives the user an idea of how it should be operated. Since you've seen and interacted with other objects with handles, the fact that a teapot has a handle allows you to infer how it should be used.

When building UIs, CSS is used to add visual affordances (e.g., adding a drop shadow and border to a button to make it look like a "real" button). However, if a user can't see the screen, then visual affordances are not conveyed to them, so we have to make sure that we construct the UI in such a way that the same affordances are conveyed to assistive technology.

Semantics, then, is the non-visual exposure of a UI element's affordances.

Semantics and the accessibility tree

But with what does assistive technology actually interact? That's where the accessibility tree comes in. When a screen reader is being used, for example, the browser turns the DOM tree into a form that's useful to the screen reader. This modified version of the DOM tree is the accessibility tree. The browser can do this because most DOM elements have an implicit semantic meaning, due to the fact that the DOM uses native HTML elements that the browser recognizes and that have predictable behavior on a variety of platforms. This built-in accessibility means that accessibility for native HTML elements (e.g., links and buttons) can be handled automatically.

But how does the browser decide which elements to add to the accessibility tree?

It inspects each DOM node and determines if it's semantically "interesting"; if it is, the node is added to the accessibility tree. Assistive technology then "walks" the accessibility tree, using it to provide an alternative UI to the user.

It's important to note that semantically "uninteresting" nodes (e.g., <div> and <span>) are often removed from the accessibility tree, especially if their only purpose is to position their children with CSS. For example, if a <button> is nested inside of 5 divs, the browser will likely remove some of the divs in the middle in order to reduce noise.

Using semantic HTML

The easiest way to convey proper semantics is to use semantically rich HTML elements. For example, a <div> and a <button> can both be styled in such a way that they provide the same visual affordances (i.e., they both look like a button). However, when using a screen reader, they provide very different experiences.

Since a <div> is a generic grouping element, a screen reader only announces its text content, which means that the user will have no idea that the element is actually meant to function as a button. A <button>, conversely, is announced as a "button", which provides a much stronger signal to the user that it's an element with which they can interact.

The simplest and best solution is to completely avoid custom interactive controls, like a <div> that acts like a button. Instead, just replace that <div> with an actual <button>. Doing so will provide the additional benefit of automatically handling keyboard interactions.

Easy keyboard wins

There are several commonly used built-in elements that have proper semantics and come with keyboard support out of the box:

  • <a>
  • <button>
  • <input> (and its various types)
  • <select>
  • <textarea>

These elements have unique interactions in mobile browsers, and attempting to reproduce them would result in a lot of extra work. This is another reason why it's best to use built-in elements whenever possible.

But how does using semantic HTML affect keyboard accessibility? Let's go back to the <div> vs. <button> example. Using a <div> as a button by adding a click handler is a common accessibility anti-pattern, and here's why.

In order to be considered accessible, a button should:

  • Be focusable via the keyboard
  • Support being disabled
  • Support the ENTER or SPACE keys to perform an action
  • Be announced properly by a screen reader

A <div> button satisfies none of those constraints, which means that additional code is required to replicate what the <button> element provides for free.

The <button> element has what is known as synthetic click activation. This means that any click handler that is added to the element will run when the user presses ENTER or SPACE. The <div> element does not have this feature, so using it as a button requires additional code to listen for the keydown event, check that the keycode is ENTER or SPACE, and then run the click handler. That sure seems like a lot of unnecessary effort given that a <button> handles all of that for us.

Wrapping up

Websites are a vital resource in today's world, so those of us who build them have a responsibility to ensure that they can be easily used by everyone. One way in which we can do so is by using semantic HTML, because it will help to automatically handle many accessibility aspects for us, requiring little to no extra code. Simple things like using a <button> element instead of a <div> element will not only reduce the amount of code that we have to write, but, more importantly, will make the UI easier to use for a keyboard-only user or provide much better context for a screen reader user.

Small changes in our code can make a big difference to our users. If we keep that in mind as we're building websites, then their accessibility will be improved as a result, and that's a win for everyone.

Want to read more tips and insights on working with a website development team that wants to help your organization grow for good? Sign up for our bimonthly newsletter.

By Rachel Opperman


What happens when you cross years of study in biology and medicine with a degree in computer science? You get someone like Rachel.