Making more accessible UIs (User Interfaces) is a collaborative process between designers, developers, and content editors. Each role must understand the others, and they each must do their part. For example, a tool created by designers and developers following best practices can still be used inappropriately by content editors, and lead to very inaccessible results; on the flip side, even accessibility-savvy content editors cannot overcome poor accessibility choices made by the designers and developers who created the service.
Web Content Accessibility Guidelines (WCAG)
What is it?
WCAGopens-in-a-new-tab is a set of recommendations created by WAIopens-in-a-new-tab. WAI is an initiative of the W3Copens-in-a-new-tab, which is an organization that has no enforcement authority anywhere in the world.
However, as discussed in the European legislation subsection, Directive EU 2016/2102 and its accompanying documents have made it possible to enforce WCAG 2.1 Level AA as the minimum standard across the EU.
WCAG 2.1 has several layers of guidance:
- Principles: web interfaces and content must be perceivable, operable, understandable, and robust. You can remember those four principles using the "POUR" acronym.
- Guidelines: each principle has a number of guidelines, which are broad goals. In total, there are 13 guidelines.
- Success criteria: each guideline has a number of testable success criteria, each of them associated with one of three levels: A, AA, and AAA (lowest to highest). In order for a digital service to comply with Level AA, it must fulfil all A and AA criteria. In total there are 78 success criteria.
- Sufficient and advisory techniques: each guideline and success criterion has an associated list of suggested techniques, which can be used to meet it at either a minimum level (sufficient techniques) or more optimally (advisory techniques). The list is non-exhaustive; this means that it's acceptable to use non-listed techniques, as long as they fulfil the guideline or criterion in question. Additionally, the same document offers a list of common failures, which are implementations that violate specific guidelines or criteria and must be avoided.
As per WCAG 2.1, web interfaces and content must be:
- Perceivable: users must be able to perceive the web interface and content with one or more of their senses. In practice, this means that web content must be perceivable by multiple senses, in order to accommodate different users.
- Operable: users must be able to use and interact with the web interface. In practice, this means that web interfaces must be operable in multiple ways, including alongside assistive technologies.
- Understandable: users must be able to understand the web content, as well as how to operate the web interface. In practice, this means that web content and interfaces must be understandable to users with different kinds of cognitive and intellectual abilities.
- Robust: the web interface and content must be reliably interpreted by different technologies. In practice, this means that the interface and content must be accessible in the present across different users and assistive technologies, and remain accessible in the future, as users and technologies evolve.
- WCAG 2.1opens-in-a-new-tab on the W3C website
- WCAG 2 layers of guidanceopens-in-a-new-tab on the W3C website
- Techniques for WCAG 2.1opens-in-a-new-tab on the W3C website
- Accessibility Principlesopens-in-a-new-tab on the W3C website
- How to understand, practice, and benefit from web accessibility by Wunder’s very own Tanja Täppinen and Otso Lahti (2022)
- Making Accessibility accessible:opens-in-a-new-tab The POUR Principles by Nozi Nindie (2018)
Hover, focus, active
What are they?
The words "hover", "focus", and (to a lesser extent) "active" are often discussed by WCAGopens-in-a-new-tab and are very important for accessibility. So let's learn what they mean (and a bit more!).
There are many interactive web elements: links, buttons, input fields, etc. To interact with any one of these elements, you can:
- Hover: by putting your cursor over it. A hovered element is ready to be activated with a mouse or any mouse-emulating technology (such as eye and motion tracking).
- Focus: a focused element is ready to be activated with a keyboard or any keyboard-emulating technology (such as switch devices).
- With a keyboard or keyboard emulator, you can tab until you get to the element in question. "Tabbing" may involve simply pressing the Tab key, or a more complex key combination, depending on your browser and settings.
- Some screen readers move focus to a focusable element when they read it. Focus then stays on that element until the reader encounters another focusable element.
- In most browsers, after you activate a button, it stays focused.
- Activate: an element is active when it's currently being, well, activated.
- With a mouse or mouse emulator, you can click while hovering over it.
- With a keyboard or keyboard emulator:
- For links: you can press the Enter key while the focus is on it.
- For buttons, selection dropdowns, and many input elements: you can press the Space key while the focus is on it.
Design and development
Hover styles help us understand that we can interact with an element. This is particularly useful for people with learning impairments, cognitive disabilities, and limited computer literacy.
Focus styles are so essential for people using keyboards and keyboard emulators, that all browsers must provide default focus styles. The
outline CSS property is used by convention because it does not affect the layout or move around nearby elements. Unfortunately, we cannot rely on the default styles alone, for the following reasons:
- Some browser defaults are simply not sufficiently noticeable.
- Most browser defaults are designed to stand out against light backgrounds, and they're not noticeable enough on dark or saturated backgrounds.
Here are some tips for implementing supplementary focus styles:
- Make sure you design focus styles that are noticeable enough, especially for people with limited vision. When a user is tabbing through, they can't predict where the next focusable item will be, so the focus style needs to catch their eye.
- Do not interfere with default focus styles: do not use
outline:noneto make them disappear, and do not use the
outlineproperty for your supplementary focus highlight or anything else. Many people who rely on visible focus to navigate have their own preferences, and use the
outlineproperty to override the browser defaults; if you're also using the
outlineproperty, you may override the user's preferences or lead to unintended results.
- If you or the client doesn't like the way the default browser focus styles look, you can use the
:focus-visiblepolyfill. It is based on a new CSS pseudoclass that might be added in the next version of CSS, to supplement the hover, focus, and active pseudoclasses. When using
:focus-visible, the browser only shows focus styles if it determines that they're needed (for example, if the user is navigating using a keyboard).
Active styles help users understand that they were able to successfully activate an element. However, since the activation time is usually quite short (the amount of time the mouse is clicked or the key is pressed), these styles should be noticeable but unobtrusive.
- Statesopens-in-a-new-tab by Material Design
- Avoid Default Browser Focus Stylesopens-in-a-new-tab by Adrian Roselli (2017)
- Stop Messing with the Browser's Default Focus outlineopens-in-a-new-tab by TJ VanToll (2013)
- Polyfill for
:focus-visibleopens-in-a-new-tab on GitHub
:focus-visibleand backwards compatibility opens-in-a-new-tabby Patrick H. Lauke (2018)
What are they?
Image content can be photos, illustrations, drawings, icons, charts, diagrams, etc. Image content can have either one of two roles:
- Informative: when it conveys information, and that information is not provided in the surrounding text.
- Decorative: when it doesn't convey information; or when it does, but the information is already provided in the surrounding text.
Informative image content must have a suitable text alternative, which can then be announced by screen readers. Text alternatives can be provided in multiple ways:
- Via the
altattribute (for elements that support it, namely
- Via ARIA-based approaches, mainly
aria-labeland (for elements that don't support the
- Via visually hidden text (also for elements that don't support the
- Don't include the words "image" or "image of". The screen reader already announces that for
<img>elements, and in other cases it's understood from the context.
- Don't just describe the content of the image in a literal or generic way.
- Ask yourself: what information am I trying to convey with this image content?
- Imagine a blind person sitting next to you. How do you tell them the information conveyed by the image?
For example, in the context of an article about one of the wheelchair tennis winners at the Rio 2016 Paralympics, don't simply write "woman on wheelchair" as a text alternative. Instead, you could provide something like "Dutch player Jiske Griffioen celebrates after winning the gold medal on the women's singles event at the 2016 Summer Paralympic Games in Rio de Janeiro, Brazil" (or whatever else the image is conveying).
The proper way to compose a text alternative depends on the context. Let's take the example of the Wunder logo, provided as an
- If it's part of a grid full of logos of all the companies supporting a project, you should use
alt="Wunder", and similarly for the other companies. Then the screen reader will come around and read: "Supported by Wunder, Apple, Google...".
- If you really need to communicate the fact that it's a logo, you could use
- If you really need to communicate what the logo looks like (for example, in the context of a design discussion), you could write something like
alt="The Wunder logo: A very stylized carrot, in a vibrant shade of purple. It has three overlapping oval-shaped leaves, and its general roundness makes it resemble a beetroot or radish".
Let's take another example. Sometimes we use card links, containing an
<img> element and a title. When we click on that link, we're taken to another page that prominently features the same image.
- On the card, the image is decorative. We should use an empty text alternative (
alt=""), so that it will be ignored by screen readers.
- On the article page, the image may be decorative or informative. Hint: if you're using some kind of stock photography, it's probably decorative!
Architects, content designers, content creators, and developers all must work together to implement good text alternative practices.
Screen reader language bugs
The screen reader voice is the voice synthesizer being used at any given time.
The language can be:
- The language of your operating system.
- The language of your screen reader UI.
- The language of the web content.
In theory, as long as the language of all content was declared properly in the code, a screen reader should have no problem choosing the correct voice. However, in multilanguage situations (for example, when the screen reader UI is in Finnish and the web content in English), many screen readers have trouble switching voices ("accents") as needed, so the user can end up listening to English text in a Finnish voice, or vice versa. In theory, as long as the language of the content was properly declared in the code, and the screen reader has the correct settings, English text should be read witn this context, the screen reader might read parts of the English text using a Finnish voice (or “accent”).
Our former colleague Xurxe Toivo García performed screen reader multilanguage experimentsopens-in-a-new-tab to study this buggy language behavior and come up with better practices.
One of the most common bugs is that text content given as an HTML attribute (for example, text alternatives provided with
aria-label) is often announced in the wrong voice. While there's nothing we can do about
<img> and the other elements where the
alt attribute is required, we do have a choice about other elements:
- We can provide the text alternative using ARIA-based approaches. This is easier to implement and maintain but often read in the wrong voice (over 50% of the time in Xurxe's experiments).
- Alternatively, we can provide the text alternative as visually-hidden text, nested inside the element in question. This is a bit harder to implement, but it will usually be read in the right voice (almost 100% of the time in Xurxe's experiments).
- Decorative Imagesopens-in-a-new-tab on Web Accessibility Tutorials by W3C
- Alternative Textopens-in-a-new-tab by WebAIM
- The troubled state of screen readers in multilanguage situationsopens-in-a-new-tab by Xurxe Toivo García (2020)
What is it?
HTML elements can be divided into two categories:
- Non-semantic: these elements don't specify anything about their content, and are simply used to group other elements, or separate certain elements from each other. The main examples are
- Semantic: these elements convey information about their content. Some are as old as HTML itself (for example, the
<p>element for paragraphs, and the
<a>element for links). Every subsequent version of HTML has added new semantic elements; in particular, HTML5 introduced many semantic elements that are necessary for improved accessibility (such as
<nav>for navigation elements and
<time>for human-readable times and dates).
How and why to use them
It's important to use semantic elements properly, so that screen readers and other assistive technologies can understand their meaning and communicate it to the user. For example:
- If you (correctly) use
<h2>elements at the beginning of sections about fruits and vegetables, a screen reader can announce them as "Heading level 2, Fruits", and then later "Heading level 2, Vegetables". Additionally, most screen readers allow the user to browse by headings, so they can understand the structure of the page or skip ahead to the sections they're interested in.
- If you (incorrectly) use
<p>elements for these headings, and then add CSS styling to make them appear bigger and bolder, users who can't see what they look like won't be able to know that they serve a special purpose. Additionally, users won't be able to browse the page by headings.
In addition to certain meanings, semantic elements that are interactive also have built-in functionality that's very important for accessibility.
Let's take a button as an example. You should use the HTML
<button> element. You could technically use a different element, such as a
<div>, and then style it using CSS. However, in order to make it behave like a true button, you'd have to do the following:
- Add the button ARIA role with
role="button", so that screen readers can announce it as such (more about ARIA roles in our ARIA section below).
- Make it focusable with
tabindex="0"so that it can be accessed with a keyboard or keyboard-emulating technology.
keyupevent handling, for at least the Space key, so that it can be activated with a keyboard or keyboard-emulating technology.
clickevent handling, so that it can be activated with a mouse or mouse-emulating technology.
All of that just to achieve the functionality you get out of the box with a
<button> element. Why make things harder than they need to be?
- HTML: A good basis for accessibilityopens-in-a-new-tab on MDN web docs
- HTML5 Accessibilityopens-in-a-new-tab by Steve Faulkner
- Semantic Structure: Regions, Headings, and Listsopens-in-a-new-tab on WebAIM
- Semantics to Screen Readersopens-in-a-new-tab by Melanie Richards (2019)
What is it?
Rich web applications (formerly known as "rich internet applications") are websites with complex features that used to be possible only in desktop applications. ARIA is designed to supplement HTML by providing additional features that facilitate and enhance the accessibility of rich web applications.
Many of the techniques that can be used to meet the WCAG success criteria are based on ARIA. However, you must use ARIA responsibly, because misusing it is more detrimental for people with disabilities than not using it at all. Always remember: no ARIA is better than bad ARIA.
There are three types of ARIA attributes that can be added to HTML code:
- Roles define the purpose of a component in the user interface.
- Properties define the characteristics of a component.
- States define the current condition of a component.
Keep reading to learn more about them!
ARIA roles convey the purpose of a component in the user interface; for example,
role="radiogroup" defines a set of radio buttons.
There are a total of 82 roles divided into six categories:
- Abstract roles: don't worry about these too much, you'll never use them directly. They exist as a conceptual basis for other roles.
- Landmark roles: these delimit major regions of the page that are navigational landmarks. They include navigation menus, search fields, footers, etc.
- Document structure roles: these tell us about the different types of content on the page and how they are organized. They include headings, tables, images, articles, etc.
- Widget roles: these are interactive elements that the user can control in some way. They include buttons, scrollbars, tab panels, etc.
- Live region roles: these are parts of the page that change content when the focus is elsewhere. They may change in response to some action taken by the user, or to some external event. They include alerts, timers, etc.
- Window roles: these are windows within the browser or application. They include dialogues, alert dialogues, etc.
ARIA properties and states
There are 27 ARIA properties, which define the characteristics of the component. For example,
aria-required="true" can tell that selecting an item from a radio group is required before a form can be submitted.
There are 9 ARIA states, which define the current condition of the component. For example,
aria-checked="true" can tell that a certain radio button is selected.
All ARIA properties and states are prefixed as
aria-*, and can be collectively referred to as "
aria-* attributes are global; they can be applied to elements with any ARIA role, or elements with no ARIA role at all. These include the commonly used
aria-hidden (which hides an element from assistive technologies) and
aria-label (which provides an accessible label for an element).
aria-* attributes can only be applied to elements with certain ARIA roles. For example,
aria-checked can be used with
role="radio" (among others), but not with
ARIA and semantic HTML
As we discussed in our semantic HTML section, most HTML elements have particular native semantics, many of which correspond to ARIA attributes (roles, properties, and states).
When using HTML semantic elements, never add ARIA attributes that are already implicit in that element. For example:
<button>element already has implicit
- A selected radio button with the
checkedHTML attribute already has implicit
Additionally, never add ARIA attributes that contradict the native semantics of that element. For example:
<button>element cannot have
role="heading"; a button is something you activate in order to perform an action, not something that gives you information about the structure of the page.
- A radio button cannot have
aria-checked="mixed"; radio buttons only support the values
false. Checkboxes, on the other hand, do support a third,
Always use semantic elements if possible, for multiple reasons:
- Native semantics have better support, especially when it comes to internationalization. For example, if you're using a screen reader in Finnish, a
<nav>element is usually correctly announced as "navigointi" (Finnish word, Finnish accent), but a
<div role="navigation">is very often incorrectly announced as "navigation" (English word, Finnish accent).
- Interactive elements have built-in functionality implemented by the browser. For example, a
<button>element works with both mouse (or mouse emulators) and keyboard (or keyboard emulators). Adding
role="button"will not automatically make it behave like an actual button.
Once again, please use ARIA responsibly. Remember: no ARIA is better than bad ARIA.
ARIA landmark roles correspond to regions of the page that are considered significant from a navigational point of view. There are eight of them:
- Banner (up to one per page): containing mostly information about the site in general, rather than the current page.
- Navigation (no limit): containing mostly links for navigating the page or the site.
- Main (up to one per page): containing the main content of the page.
- Complementary (no limit): containing information that supplements the main region, but can still be seen as a separate entity.
- Content info (up to one per page): containing information about the page or site.
- Form (no limit): containing one or more elements that make a form (but not a search form).
- Search (no limit): containing one or more elements that function as a search facility.
- Region (no limit): for content sections that are large and important enough to be considered a major landmark but are not suited for any of the other landmark roles.
Certain elements introduced in HTML5 have these ARIA roles as part of their implicit semantics. For example, the
<main> HTML element has the implicit
role="main", and we shouldn't explicitly add it to the code. Here are the relationships:
formrole.There is no HTML element that has an implicit
searchrole. In most cases, we will use a form element and give it the explicit
All the content of a page should be contained by ARIA landmarks: some assistive technologies (such as screen readers) have shortcuts to go to specific landmarks, or to the beginning or end of the current landmark. Any content not inside a landmark could be missed by these users.
Some landmarks are top-level only:
<footer> cannot be inside other landmark regions. The rest are allowed to be nested if necessary, but it's not required. For example, a
<nav> element can be at the top level or nested inside another landmark (such as
Only some landmarks can occur multiple times in a page (see earlier list): if there are multiple landmarks of the same type, they must be distinguished with the use of
aria-labelledby. For example, you may have a primary navigation bar (identified with
aria-label="primary") at the top of the page, and a secondary navigation element (identified with
aria-label="secondary") inside the footer.
- ARIA 1.2opens-in-a-new-tab on the W3C website
- ARIAopens-in-a-new-tab on the MDN web docs
- Latest ARIA Authoring Practices Guideopens-in-a-new-tab on the W3C website
- "No ARIA is better than bad ARIA"opens-in-a-new-tab on the ARIA Authoring Practices Guide
- Categorization of rolesopens-in-a-new-tab on ARIA 1.2
- Supported states and propertiesopens-in-a-new-tab on ARIA 1.2
- Landmark Rolesopens-in-a-new-tab on ARIA 1.2
ARIA and HTML:
- ARIA in HTMLopens-in-a-new-tab on the W3C website
- Document conformance requirements for use of ARIA attributes in HTMLopens-in-a-new-tab on ARIA in HTML
- Allowed ARIA roles, states and propertiesopens-in-a-new-tab on ARIA in HTML
- ARIA Landmarks Exampleopens-in-a-new-tab on the W3C website
- Semantic Structure: Regions, Headings, and Listsopens-in-a-new-tab on WebAIM (2020)
- Accessible Landmarksopens-in-a-new-tab by Scott O'Hara (2018)
Wish us to audit or enhance the accessibility of your digital environment?
Send a message to our expert or fill in the form below and we will contact you!
Head of Design[email protected]