Introduction
Who Are Webpages For?
It is obvious that one of the primary uses of webpages is to convey information. When one uses a website, what that means by majority time spent is almost invariably reading, even if the overall goal is to submit information or carry out some other action.
It can be easy to forget all about the technology which makes up the membrane of access and interaction with webpages as most of us surf the web as absent-mindedly as we drive our cars, but the fact that we are interacting directly only with browsers has important implications for how web pages can be understood as the web’s grammar of content. Before a webpage can convey information to you, it must first convey information to your browser, a machine which directly empowers the Human to interact with the system - a user agent.
This is an extremely important feature of webpages which set them apart from many other modes of Human communication; they are primarily designed to be interpreted by machines. As any software developer will tell you, communicating with machines is not at all like communicating with Humans. Machines demand structure, consistency, and explicitness where Humans may fall back on inference and contextual analysis. The power of structuring content for a machine lies in that the content is not really structured for a particular machine, but for any entity with knowledge of the syntax.
The Promise of The Web
By formatting information in a rigorous structure, webpages make themselves available to many different kinds of machines, not all of which are interested in rendering their interpretation to a visual display or are even operated by Humans.
Web crawlers, the vanguard programs which make search engines and large-scale internet research possible, do not care about the spatial positioning of UI elements, nor do they understand ASCII art or that red text should signify emphasis. These exceedingly powerful and important machines, as Jeffrey Zeldman has pointed out, are functionally blind.
If blind machines can interpret webpages, it follows that they are in-turn able to present them non-visually to Humans. This is precisely the purpose of screen reader software like NVDA (NonVisual Desktop Access), which interfaces with standard visual browsers to present webpage information audibly.
The promise and potential of the web is that this works out of the box. When crafted properly to convey meaning, HyperText Markup Language, HTML, has everything screen readers like NVDA need to render the content of the page into the airwaves as browsers render it onto monitors. It also affords means of interaction for those using all sorts of user-agents, including those who use a keyboard only and those who use voice-controlled browsing technologies.
This represents a brave new world of possibilities for those who are unable to process visual information or have other impairments. Where commonly they would require information mediums specifically crafted for them, such as braille magazines, books, and newspapers, webpages can in theory be equally accessible to people using all kinds of user-agents and technologies to engage according to their unique ability set. Not only do we have the Library of Alexandria at our fingertips, we also have it at the tips of our tongues and at the flick of our eyes.
Our Crossed Fingers
There is a tendency among software developers to view their craft as transcendental. Programming is difficult, and with it you can do a lot of very cool things. Therefore, the act of crafting procedurally executing programs is the highest and most important skill to learn; once that skill is attained, spending time on other things is a comparative waste. As Folding Ideas put it, specifically about programming with cryptography, “all other complicated things must be lesser in complexity and naturally lower in the hierarchy of reality, nails easily driven by the hammer that they have created.”
This mentality is pervasive; it is an extremely common sentiment among software developers that font-end, i.e., user-facing, development is naturally easier and less interesting than back-end, i.e., business logic, development. HTML (and its styling language, CSS) is commonly dismissed as “not a programming language”, which, while true in the strictest sense of the words, is not a valid reason for dismissal. It is openly ignorant of the power of semantic HTML and disdainful of the effort required to learn how to properly construct it. This is not always a gendered indictment, but it certainly can be; to some, any skill which might consider user experience or aesthetic design is more feminine than the logic-forward “masculine” and “detached” craft of business logic. The predominance of men and masculine culture among developers does have a part to play in the prevalence of this opinion among software professionals.
This sentiment is reflected by a talk the CEO of the company I work for which described crafting prompts for modern Large Language Model programs as “more like web development than programming.” This is a value judgement about the worth of two related skillsets which is very funny coming from someone whose company’s primary product is a web application.
The result of this is that there is a massive knowledge deficit among web developers, especially younger developers, about how HTML is meant to function. Frequently, we receive no explicit training on HTML; the knowledge is often just assumed as obvious. It is not, as evidenced by the utter haplessness of many developers using CSS and the ubiquity of non-semantic elements where they do not belong. The web, crafted by these unskilled hands, sees HTML as an antiquated front-end library for their thick-client scripting language apps that we’re simply stuck with for historical reasons.
When an end-product webpage influenced by these social forces does not rely on third-party UI libraries, it often fails to follow established best-practices despite decades of maturity in the paradigm. Even when third-party UI libraries, or even accessibility-focused libraries, are used, they cannot fully mask a lack of basic understanding of how the technology functions by the Humans assembling the components – there will be mistakes which will either go unnoticed entirely or will be extremely difficult to resolve due to a lack of familiarity with the underlying system.
The impact of this is obvious, and tragic. The WebAIM Million report in 2023 found that 96.3% of surveyed home pages had accessibility errors – failures to meet the World Wide Web Consortium’s Web Content Accessibility Guidelines version 2.1 at level AA – the gold standard of web accessibility. The web is a great opportunity for equitable access to information like we’ve never seen, and we are failing to live up to its potential.
Where Do We Go from Here?
Web technology did not get us into this situation, human behavior and paradigms did. Therefore, our best way out of this is a Human solution – education.
Any developer who creates webpage content should respect the technology enough to understand how it works. Most developers, fortunately, have at least a basic grasp of HTML, but fail to spend the time needed to understand it deeply enough to create content which has true semantic meaning on top of visual associations. This is not an easy skill, but it is eminently learnable; there are numerous resources and courses available, but the only way to really understand is by doing. It is my opinion that any web developer should spend time interacting with the DOM directly, frameworkless, and that they should spend time learning the basics of screen reader operation.
I’m going to use the rest of this blog post to pass along some of the knowledge I’ve accrued about structuring webpage information accessibly both from constructing this website and from my day job.
Labelling Data
When a data element, or an input element, is displayed on a webpage, the most important semantic association it has is its name, which will inform users what it is referring to. This concept is called an accessible name, and there are multiple techniques possible to create this meaning using the structure of the page itself.
<label>
<label> is the dedicated HTML element for labeling UI elements, primarily <form> elements.
<label>s are associated with elements by specifying the element’s ID in the for property (or by nesting the element inside the <label>).
Only labelable elements will be meaningfully associated. These are:
Other elements will not have their accessible name specified by a <label> out of the box. One framework technique I’ve seen, though is to have a control use scripting to scan the DOM for labels which reference it, and then set its accessible name programmatically. On top of being over-engineered, this is a fragile pattern since the content of the label can conceivably change after the control is constructed, leading to mismatches. It is better to label controls using accessible attributes directly, as discussed later.
UI elements not structurally associated with their labelling text fail WCAG 1.3.1 – Info and Relationships (Level A). This is an upsettingly common failure since it’s fairly basic to get right; looking at it positively, this means that minimal education can yield substantial benefits.
Labelling Multiple Elements & Multiple Labels
Associating one <label> with multiple elements or one element with multiple <label>s can cause issues with screen readers and is not recommended.
One good alternative is to group elements under a <fieldset>; screen readers ensure that the <fieldset>’s name is presented to the user in addition to the normal label.
Additionally, it is possible to specify multiple labels for an element using semantic properties. This is discussed next.
aria-label & aria-labelled-by
The Web Accessibility Initiative specifies a set of HTML techniques to explicitly configure information accessibly, called the Accessible Rich Internet Applications suite, or WAI-ARIA. The element attributes in this suite may set the accessible name on HTML elements. Generally, an element’s accessible name is determined automatically by related HTML elements, e.g., <table>s are named by their <caption>, but WAI_ARIA offers a superset of these associations which often better afford determining names dynamically via scripting.
aria-label is specified on the labelled element as a string, and it used directly as the element’s accessible name.
aria-labelledby is specified on the labelled element as a space-delimited list of IDs of labelling elements. The inner text of these elements joined together is considered the element’s accessible name.
These attributes, usefully, can name a wider array of elements than <label>s.
Here are some general rules of thumb for using ARIA attributes:
- Use <label>s or semantically associated HTML elements if you can instead.
- Prefer aria-labelledby over aria-label to provide a consistent experience for all users.
- aria-labels are intended primarily for interactive elements.
Anti-Patterns
With very few exceptions, elements with visible text should not be assigned a different accessible name with aria-label. This creates an inconsistent experience for users who use screen readers and users who do not. Our goal, as the architects of web applications, should be Universal Design where at all possible.
Additionally, changing the accessible name of interactable elements from their visible label can have negative implications for those using voice-controlled technology.
Branching logic based on user-agent type and extensive additional handling unique to nonvisual interaction also makes code more difficult to maintain. While developing, the goal should be to write as little WAI-ARIA and user-agent-specific logic as possible, opting instead for semantic HTML and universal design.
See also: Bad ARIA Practices.
Providing Additional Context
In addition to the accessible name of an element, there is also the concept of an accessible description.
An accessible description may be used to provide more information about a UI element beyond the basics of what it is. This is done by using the aria-describedby attribute. Like aria-labelledby, it is specified as a space-delimited list of element IDs.
There is also aria-details, which is meant to work like aria-describedby without reducing the description to plain text; the description itself may have HTML structure. However, this feature is currently poorly supported by screen readers.
Labelling Strings
<label>s can only be structurally associated with labelable elements; non-editable text elements like <span>s are not able to be linked to <label>s.
The preferred method for presenting non-editable string information is to do so in one element. For example:
<span>SPARTAN TAG: 117</span>
That said, this is not always easy for styling reasons. <label>’d text is still accessible provided the elements are adjacent in the DOM.
Relatedly, non-interactive text should not be in the tab order; they are accessible to screen readers with Browse Mode, which allows users to scan a page's contents irrespective of focusability.
To avoid implying that it may be editable in some conditions, we should not use read-only fields for text that is never editable.
Multiple string data values associated with labels is a good use-case for <table>s.
Tables
Data Tables
<table>s are a great tool for presenting information accessibly.
Specifying the scope property on the header, <th>, elements define their associative directions. This is important for large or complicated tables.
S Tier | Garrus Vakarian | |||||
---|---|---|---|---|---|---|
A Tier | Tali'Zorah nar Rayya | Urdnot Wrex | Legion | Mordin Solus | ||
B Tier | Liara T'Soni | Grunt | Thane Krios | Jack | James Vega | EDI |
C Tier | Zaeed Massani | Samara | Kaidan Alenko | |||
D Tier | Miranda Lawson | Jacob Taylor | Ashley Williams |
Screen readers provide features to easily navigate through tables which rely on them being set-up properly and only used for presenting data.
Layout Tables
Aside from presenting data, <table>s are also sometimes used for layout purposes. This was more common before modern CSS layouts:
- Flexbox (W3C Candidate Recommendation in 2012)
- Grid (W3C Candidate Recommendation Draft, widely supported in 2017).
Grid was originally implemented in IE, and it still has partial support!
Implemented improperly, using <table>s can introduce accessibility issues, especially if they are interpreted by the user-agent as data tables. User-agents tend to guess about this, so testing is important.
Layout tables are, overall, difficult to maintain and are recommended against by the W3C.
Landmarks
Structuring a Page
Representing the logical structure of a page explicitly in HTML (and not just visually) is achievable via Landmarks.
Landmarks are a set of element Roles, a semantic concept of what the element is intended for. This concept lives alongside accessible name and accessible description.
There are eight available Landmark Roles:
- Banner
- Complimentary
- Contentinfo
- Form
- Main
- Navigation
- Region
- Search
These roles allow users to both identify what section of the page they’re in and to quickly navigate between landmarks. For example, the NVDA Elements List popup provides a list of landmarks on the current page, as well as its headers, links, and form elements.
HTML Sectioning Elements
Common components of webpages, as specified by semantic HTML elements, are associated with a predefined set of roles.
HTML Element | Default Landmark Role |
---|---|
<aside> | Complimentary |
<footer> | Contentinfo when in context of the <body> element |
<header> | Banner when in context of the <body> element |
<main> | Main |
<nav> | Navigation |
<section> | Region when it has an accessible name using aria-labelledby or aria-label. |
One common pattern seen in a lot of webpages is to include a link in the banner to the <main> element, so that keyboard-only users may skip past repeated elements across multiple pages. Non-keyboard-only users frequently don’t notice these links since they are generally stylistically hidden until focused. In my experience, the presence of such links is a hallmark of a website which takes accessibility seriously.
Conclusion
This post is by no means comprehensive, but it is a hearty chunk of information I had ready to go. I plan to expand on more technical topics in follow-up posts, but in the interest of digestibility we’ll end here. I kind of like this style of more technical blogging; I’ll have to do it more often.