Skip to content

Accessibility Project

Robust

Content must be robust enough that it can be interpreted by a wide variety of user agents, including assistive technologies.

For a developer this means that a site needs to be built with assistive technologies, like screen readers, in mind. For the most part, using semantic HTML gives you this automatically.

Semantic HTML

Semantic elements describes their meaning to the browser as well as the developer. Let's take a look at an example, using a simple dummy site:

Example: Divs or Semantic Elements?

Using <header> for your header or <nav> as your element containing your links instead of a generic <div> helps assistive technologies like screen readers to navigate the site and are considered best practices.

Example Site

Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet consectetur adipisicing elit. Laboriosam, eius.

Lorem, ipsum dolor

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nihil excepturi maxime distinctio! Quis, ducimus sed.
© My Site

As long as the elements get the same styling, the result on screen will be the same. Here's a version made with non-semantic elements:

<div>
<div>
<div>Example Site</div>
<div>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</div>
</div>
<div>
<div>
<div>Lorem ipsum dolor sit amet</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Laboriosam, eius.</div>
</div>
<div>
<div>Lorem, ipsum dolor</div>
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nihil excepturi maxime distinctio! Quis, ducimus sed.</div>
</div>
</div>
<div>
© My Site
</div>
</div>

Compare it to this version using semantic HTML elements:

<div>
<header>
<h1>Example Site</h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
</header>
<main>
<article>
<h2>Lorem ipsum dolor sit amet</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Laboriosam, eius.</p>
</article>
<article>
<h2>Lorem, ipsum dolor</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nihil excepturi maxime distinctio! Quis, ducimus sed.</p>
</article>
</main>
<footer>
© My Site
</footer>
</div>

The semantic version is easier to read and understand, and much better from an accessibility standpoint.

A woman working at an office desk with three screens with code.

Creating My Own Form

So we've established that you should use semantic HTML whenever possible. But what happens if you code something that for any reason looks a bit different? Let's take a look at at this specific criterion:

Name, Role, Value

For all user interface components (including but not limited to: form elements, links and components generated by scripts), the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies.

In practice this means that if you create your own piece of code, you need to make sure important accessibility parts like aria roles and labels are present.

Example: My Cool Form

I want to add a small form on my site where a user can send in their name for a competition. Usually a form in React is structured something like this:

<div>Name Form</div>
<form onSubmit={handleSubmit}
<div>
<label htmlFor="name">Name:</label>
<input
type="text"
id="name" name="name"
value={formData.name}
onChange={handleChange}
required
/>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>

Which looks something like this:

Name Form

However, for this small form I want something tighter and just use a placeholder instead of the label:

<div>Name Form</div>
<form onSubmit={handleSubmit}
<div>
<input
type="text"
placeholder="Name"
id="name" name="name"
value={formData.name}
onChange={handleChange}
required
/>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>

This is my reworked form, note that there is no label next to the input.

Name Form

At this point everything looks ok and I get no errors in my editor. However, since the label for the input is missing, a visitor using assistive technology will have trouble interacting with the form — and my site will be in violation of the WCAG 4.1.2 rule as stated above. Uh-oh!

So what's the solution? Since the <label> is missing I don't get the accessibility automatically. After going over to MDN and reading about the issue, I see that a form MUST have a visible label of some sort.

Hm! Ok, I might have an idea.

I have a descriptive text at the top of my form, that could act as my visible label by adding aria-labelledby to the <input> element and a corresponding id to the text.

<div id="nameform">Name Form</div>
<form onSubmit={handleSubmit}
<div>
<input
type="text"
placeholder="Name"
id="name" name="name"
value={formData.name}
onChange={handleChange}
aria-labelledby="nameform"
required
/>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>

This works and fulfills the WCAG criterion, but is "Name Form" as clear and understandable as our original label of "Name"? No, probably not since the latter is the standard formulation. That's why it's ususally a good idea to stick to the establish method of <input> and <label> where possible.

A few final notes:

Textboxes like an <input> can't use aria-label on it's own beacause it's supposed to have a separate, visible <label> element.

You should use a <label> for each <input> element. Another solution would've been to rework the <label> from our first form and style it to look more like the title.

By using aria-labelledby, several elements could reference the same id.