thinking about accessibility
The effects of semantics on accessibility.
08 June 2023When browsing the web, assistive technologies convey information to their users by reading through the HTML of web pages. If the structure and content of our web pages is not clearly conveyed in the HTML, users of assistive technologies (and keyboard users) will likely have a hard time navigating through our websites and applications, and ultimately leave.
The visual stylings of CSS and interactivity of JS are inconsequential to assistive technologies and keyboard users. If an
<li>
element is defined as the third item in a list, it doesn't matter if its visually depicted as the first one; the screen reader sees it as the third item, not the first.
That's not good for them, which means it's not good for us. The good thing is their experience can be improved by articulating the structure of our web applications better. Using semantic HTML helps us do this, but... does it just work out of the box, and boom - accessibility everywhere?
HTML defines the structure and content of web applications and can be both semantic and non-semantic. Semantic HTML communicates to both web browsers and developers the meaning of the content they enclose. For example, a
<header>
element communicates introductory content such as the heading of the web page, it's logo and/or navigation aids. Non-semantic HTML does not communicate any information about the content they enclose, for example<div>
and<span>
elements. They are purely decorative.
I've been increasingly wondering about this - the correct usage of semantic HTML and it’s effects on accessibility, and so like any other sensible person I turned to Google for my answers. I was concerned with the following:
- Is it semantically correct to place a
<header>
element inside the<main>
element, or shall I re-work a plethora of projects these coming days?
There can be more than one
<header>
element inside an HTML document, but no more than one<main>
element.
- I use
<ul>
and<li>
elements inside<nav>
elements. How does this make my navigation aids more accessible?
What I found was interesting, and ultimately the answers to both these questions is: it depends.
Let's start with the first one: a <header>
element inside the <main>
element.
a <header>
element inside the <main>
element
Note: Throughout this discussion the <header>
element I am referring to is one which would be placed at the top of each web page in a website, and include contents such as a logo, search bar, or navigation bar.
The MDN documentation defines the <header>
HTML element as an element which "represents introductory content, typically a group of introductory or navigational aids. It may contain some heading elements but also a logo, a search form, an author name, and other elements."
Okay. So, the logo and navigation aids can stay inside the <header>
element, but where do I put the <header>
element when structuring a web page? Thankfully the technical summary on the <header>
element’s documentation has a note on permitted parents which helps answer my question.
For a <header>
element, permitted parents include “any element that accepts flow content”. But, a <header>
element must not be a descendant of an <address>
, <footer>
or another <header>
element. Meaning, the <header>
element can be placed inside the <main>
tag. But (again), there's a catch 22 at play here. Depending on its parent, the role of a <header>
element changes (*cue dramatic music). It's implicit ARIA role is a banner
, but when placed inside an <article>
or a <main>
element (among a list of other types of elements), it has no corresponding role.
Now the answer to my question would depend on the role the <header>
element would assume in the context of a web page and that means understanding the banner role.
The banner
role is defined in the MDN documentation as "defining a global site header, which usually includes a logo, company name, search feature, and possibly the global navigation or a slogan. It is generally located at the top of the page." And there we have it.
If I want the <header>
element to assume this role I'd have to define it at the top of a web page, meaning outside of the <main>
element. If the content it contains doesn't fit the role of a banner
, placing it inside containing parent elements would be fine. In this case, it does fit the role, so it should be placed outside of the <main>
element.
What's more, the <main>
element "represents the dominant content of the <body>
of a document" and its content should be unique. The content inside the <header>
element isn’t unique to the page and instead will be visible on all pages on the site.
The Verdict
I'll be re-working some projects over the course of a few days by moving <header>
elements outside of <main>
elements because their current placement is semantically inaccurate.
<ul>
and <li>
elements inside <nav>
elements
In days long past before the advent of the HTML5 specification, to markup navigation elements our ancestors developers used <ul>
tags with a role=''navigation'
. Their navigation systems often looked like this:
<ul role="navigation"> <li> <a href="/">Home</a> </li> <li> <a href="/">About Us</a> </li> <li> <a href="/">Contact Us</a> </li> </ul>
The HTML5 specification gave us the <nav>
element, and suddenly we could do something like this:
<nav> <ul> <li> <a href="/">Home</a> </li> <li> <a href="/">About Us</a> </li> <li> <a href="/">Contact Us</a> </li> </ul> </nav>
Or more concisely, this:
<nav> <a href="/">Home</a> <a href="/">About Us</a> <a href="/">Contact Us</a> </nav>
Both are perfectly valid HTML, but which is more accessible?
Well, I tested both versions - <nav>
elements with <ul>
elements and another without - using screen readers (namely Screen Reader Chrome extension), and here are the results:
- With
<ul>
elements: "Navigation. List with 3 items, Home, link, list item. About Us, link, list item. Contact Us, link, list item." - Without
<ul>
elements: "Navigation. Home, link. About Us, link. Contact Us, link."
The Verdict
Undetermined. Historically <ul>
elements were used to group navigation links, but with the introduction of the <nav>
element, that's no longer necessary. Including the <ul>
elements inside the <nav>
tag is valid HTML, but when accessed by screen reader users, navigation systems marked up using <ul>
elements might be creating a bit of noise. The list item information might be overly verbose in this context, which might impede how screen reader users experience and interact with such navigation systems.
Interested in seeing how others have implemented their navigation systems, I checked out websites create by prominent organisations (because I assume they know what they are doing) namely GitHub, Google Fonts, and the MDN documentation website.
When navigating through GitHub's navigation system using a screen reader, the list items are not included in the narration. However, when navigating through the MDN documentation website and some of the navigation systems on Google Fonts, they are. Not promising.
Concerning maintainability of the codebase, omitting <ul>
elements makes for shorter, more concise code, all the same achieving (somewhat) the same effect, albeit the differences in how screen readers narrate the navigation system. However, when augmenting the navigation to include submenus, lists might be the most viable (and semantically correct) solution to use for markup compared to solutions which use <div>
elements instead.
For now, I'll leave them and not throw caution to the wind for my future self or fellow contributors. The extra context though seemingly verbose (for example on Google Fonts: Common actions. Navigation. List with 5 items) might possibly be helpful.
TidBytes
Strangely enough, when using Narrator on Windows to access the MDN documentation website, Narrator does not announce the top navigation system of the website in the same manner as the Screen Reader extension does.
- Narrator: "Main menu. Link. References."
- Screen Reader: "Navigation. List with 4 items. List item. References."