Unlocking Web Accessibility: The Crucial Role of Semantic HTML in Inclusive Design

Is learning HTML actually important?

Y 👏 E 👏 S 👏! Too many people jump right into learning React these days without understanding the fundamentals of HTML, CSS, and JavaScript. It can be tempting to skip the "easy" stuff and just learn it on the job, but you are setting yourself up for failure. Using HTML incorrectly can lead to severe accessibility issues and poor user experience. Let's explore some examples and learn how to craft better semantic HTML.

UI Controls

UI controls are the parts of your application the user actually interacts with. Think inputs, buttons, forms etc. These are arguably the most important things to use semantic HTML for, as you want users of all abilities to be able to perform actions and interact with your website. Unfortunately, developers do not always use semantic HTML for UI controls, and can end up falling into bad patterns that can make their sites unusable to some users.

Can you tell the difference between these two input/label implementations?

My Cool Input Label

It may not be obvious to the naked eye, but if you inspect the elements and poke around at the code, you can see they are very different. One of them uses a div with an onClick to focus the input, (which is something I actually saw in a real code base!) while the other uses semantic HTML to wrap the input in a label.

BadReactInputFocus.jsx
accessible-html-input.html

import { useRef } from 'react';
export function BadReactInputFocus() {
const inputRef = useRef();
function focusInput() {
inputRef.current.focus();
}
return (
<>
<div className="mb-2 cursor-default" onClick={focusInput}>
My Cool Input Label
</div>
<input
className="border p-2"
placeholder="My cool input text"
ref={inputRef}
type="text"
/>
</>
);
}

Clearly, the good example using a label is better for many reasons. It does not require shipping extra JavaScript to focus the input on click, it tells screen readers what the input is, and it conveys meaning to search engines. This is exactly what labels were meant for, and every input should have a corresponding label.

What about these buttons? Are they the same?

Click me!

You may have already guessed this, but these are definitely not the same. One of them uses a <div> to create a fake button and the other uses a semantic <button> element.

fake-buttons.html
semantic-buttons.html

<div
data-message="Yay, you clicked the button!"
class="rounded bg-gray-200 p-2 text-sm text-black transition-colors hover:bg-gray-300"
onclick="(function(element) { alert(element.getAttribute('data-message')); })(this)"
tabindex="0"
role="button"
>
Click me!
</div>

Whenever possible, you should always use a button for things the user can click on to perform actions and if that action is transitioning to another page, it should instead be an anchor tag. As a general rule, it's better to use real elements instead of faking their type with role as well.

Text Content

Text content may not seem as important as UI controls, after all, won't people just be reading it the way you style it? Well, not necessarily. For people using screen readers, bad semantics can lead to a very confusing experience. Not only that, but your SEO will suffer if you are not using things like headings to call out what is important on your page.

Which of these examples is using correct semantic markup?

Example 1:

Heading
This is the first section of my document.
This is another paragraph.
1. First item
2. Second item
Subheading
This is the first subsection of my document.

Example 2:

Heading

This is the first section of my document.

This is another paragraph.

  1. First item
  2. Second item

Subheading

This is the first subsection of my document.

BadTextSemantics.jsx
GoodTextSemantics.jsx

export function BadTextSemantics() {
return (
<>
<span className="text-3xl">Heading</span>
<br />
This is the first section of my document.
<br />
This is another paragraph.
<br />
1. First item
<br />
2. Second item
<br />
<span className="text-2xl">Subheading</span>
<br />
This is the first subsection of my document.
</>
);
}

Both of these achieve essentially identical results to the naked eye, and someone who does not know about headings and paragraphs may be tempted to use this non-semantic approach to achieve the look they were going for. This is why it is important to always educate yourself on which semantic HTML elements exist and their use cases, to ensure you are producing the most accessible applications.

Wrapping up

This only scratches the surface of the true impact semantic HTML makes on the usability of your site for your users. As the web evolves, we are only going to have more and more ways to interact with it, so thoughtfully using semantic HTML is going to be the best way to ensure you are providing the best experience for all users on all devices.

Anything major I missed covering or just want to reach out and geek out about HTML? Hit me up on Twitter! @RobbieTheWagner.

Sources

Major shout out to MDN for their great article HTML: A good basis for accessibility. A lot of the examples here were heavily influenced by it, so definitely check it out if you want to learn more great tips and tricks for using semantic HTML effectively!