November 08, 2019 Albéric Trancart 13 min read

Web accessibility (a11y) can be a little disorienting for everyday developers. Here is a practical, down-to-earth guide with examples to help you make your websites more inclusive and comply with legislation.

Why is accessibility important?

There are three main reasons why you should make your apps and websites more accessible:

Inclusiveness: accessibility is making your site usable by the widest range of people, and not exclusively screen readers. For instance, there are more color-blind people (4.3%) than Internet Explorer/Edge users (3.3%). Furthermore, disabilities can be temporary or situational, so a more accessible Internet helps everyone.

accessibility is making your site usable by the widest range of people, and not exclusively screen readers. For instance, there are more color-blind people (4.3%) than Internet Explorer/Edge users (3.3%). Furthermore, disabilities can be temporary or situational, so a more accessible Internet helps everyone. SEO: although this is only a small factor for SEO, well-structured content will be easier to read and easier to parse for search engines.

although this is only a small factor for SEO, well-structured content will be easier to read and easier to parse for search engines. Legal: even if you don't care about the two points above, making your code accessible is now a legal obligation. US websites must comply with the WCAG standard and EU websites (for all public agencies and private companies with revenues over 250 million euros) to the EN 301 549 V2.1.2 norm.

What is the RGAA?

The RGAA is the French government's official guide to improving accessibility. It features a verification method, tests, and checks to enforce both the WCAG 2.1 AA standard and the EN 301 549 V2.1.2 norm.

You can download it here (link in french): Référentiel général d'amélioration de l'accessibilité.

However, it is not so easy to digest - there are 13 categories of criteria across 120 pages. Let's break it down category by category to get the essential information.

I recommend that you audit one of your web pages while reading this article to put it to practice. I made a nice printable a11y checklist for you to follow along. You also may want the HTML tags reference page opened in another tab. That will come in handy for understanding the role of HTML tags you may not know or improve your knowledge of the ones you already know.

Disclaimer: following these rules will not guarantee that your site is 100% accessible. It will not replace real user tests. It will make your site easier to navigate for everyone, though.

RGAA check categories

Let's go! To give some examples, I'll use Falco, Theodo's open-source WebPageTest runner and SpaceX Stats, my space-themed project as test dummies.

Warning: checking each category changes a lot from page to page and can take some time.

Images

People using screen-readers should be able to understand the content without the visual information provided by the images.

All meaningful images must have a relevant text alternative. <img> tags must have an alt attribute while <svg> , <canvas> , <embed> , <object> and tags with role="img" must have a aria-label attribute.

tags must have an attribute while , , , and tags with must have a attribute. Decorative images should be hidden with an empty alt="" attribute for <img> tags or aria-hidden="true" for other tags.

attribute for tags or for other tags. Images required to understand the content point to a description with aria-describedby .

. Images containing text (memes are a perfect example) have a text alternative containing the text of the image

If the image has a legend, it must be in a <figcaption> tag

tag If the image is a CAPTCHA, there is a non graphical alternative to the CAPTCHA

Bad example: this image has a wrong alt attribute, it is not relevant to the image

Bad example: this image should have alt=""

Bad example: this svg should be aria-hidden="true"

Colors

Good colors and contrast are especially important for color-blind people, people with vision conditions such as myopia or simply all users over the age of 40.

Choose colors with a high enough contrast Text smaller than 24px should have a 4.5:1 ratio (don't forget video subtitles and text on images) Text bigger than 24px and UI elements such as icons, borders, buttons, charts... should have a 3.0:1 ratio There are exceptions: elements in their disabled state, logos, decorative text, inputs with native browser styles are not subject to this rule

Colors should not be the only mean of conveying the information, such as chart colors or medical diagrams. For instance you could use different chart line styles or provide a long description.

You can check color contrast in one click with this extension: WCAG Color Contrast Checker for Chrome, WCAG Color Contrast Checker for Firefox.

Good example: Falco is OK for color contrast

Here is an article on how Stripe chose its color palette to meet these criteria.

Content

A well structured content is easier to understand, especially for people with screen readers.

The lang attribute is set on the html element

attribute is set on the html element The titles <hx> structure is relevant (do not skip heading levels)

structure is relevant (do not skip heading levels) There are <header> , <footer> , <nav> , <main> , <article> , <section> and <aside> elements when relevant

, , , , , and elements when relevant All links have relevant wording or title attributes for composite links (images as link...)

List contents are using <ul> / <ol> / <li> / <dl> / <dt> / <dd>

/ / / / / Quotes are using <blockquote> for long quotes and <q> for short quotes

for long quotes and for short quotes Each <iframe> has a title attribute describing its content

has a attribute describing its content Cryptic content, emojis, ASCII art... have text alternatives

The HTML is valid.

You can understand the page with a screen reader only.

For screen-reading, you can use VoiceOver on macOS or this Google Chrome extension if you prefer Linux like me.

To validate your HTML, you can enter your URL or copy-paste the generated HTML into the official validator.

Bad example: the text given by the screen reader is difficult to understand, and it's even worse when it's read aloud

CSS

Aging people often use zooming features,

The content is still readable if I disable CSS

The website is still usable if: I set the font-size to 200% or use the browser zoom to 200% I set line-height to 1.5rem, margin between <p> to 2rem, letter-spacing to 0.12rem, word-spacing to 0.16rem

There should be no horizontal and vertical scrolling at the same time on a page (that would translate to "no horizontal scrolling" on normal websites)

The website should be readable in landscape and portrait mode (exceptions: apps such as games, etc)

A quick code snippet you can paste into the devtools in the <html> element to check text resizing:

font-size : 200% ; line-height : 1.5rem !important ; letter-spacing : 0.12rem !important ; word-spacing : 0.16rem !important ;

Bad example: the layout is broken...

Navigation

Keyboard navigation is important for users with motor disabilities, people having tremors, blind users but also power users of the website.

You can use every feature of the page with the keyboard only

Every hidden content has display: none or set a aria-hidden="true" attribute

or set a attribute Focusable elements have a focused style, and it is not only a color change

At least two navigation systems exist: menus, sitemap, page search (exceptions: small enough sites where browser search acts as a page search)

Navigation systems are at the same place from page to page

There is a "Skip to content" link as the first focusable element

Bad example: the outline is disabled on this link

Good example: you can steal GitHub's "Skip to content" link. Hidden by default but it's the first focusable element and it appears if you Tab into it.

Media

Media often convey a lot of information that can't be accessed with visual or auditive conditions.

Use native <audio> and <video> players, no other technologies such as flash

and players, no other technologies such as flash Provide subtitles with <track kind="captions"> to both audio and video content (don't forget user-uploaded content!)

to both audio and video content (don't forget user-uploaded content!) Other types of media (carousel, slides, etc.) must have textual alternatives

Do not autoplay media

Downloaded files should be accessible or have an accessible alternative

Bad examples: both Falco and SpaceX Stats are using charts with no tabular alternative. Here are some examples of accessible charts with Highcharts

My opinion: providing text alternatives to complex media such as videos and charts is clearly the hardest criteria to meet. My personal strategy would be to limit the usage of such media and to have a text with a similar level of information in descriptions labeled with aria-describedby . When having user-uploaded content, you should encourage your users to provide a long description too. However, when these media are the main focus of the website (such as YouTube or TED), you can't escape the need for captions.

Tables

A well-structured table is important for screen readers, as a badly structured one can become really confusing.

<table> is used to display tabular data and only tabular data

is used to display tabular data and only tabular data The table is described by a <caption> tag

tag The table has a title attribute

attribute The table has <th> row and/or column headers

row and/or column headers Every cell is linked to its header by putting scope="rol" / scope="col" on the <th> elements or by linking <td headers="super-header-id"> with <th id="super-header-id">

Bad example: this table is missing a caption and could use row headings on the mission names

Forms

Forms are sometimes complex to understand and to navigate, and it is even worse for people with screen readers or using keyboard navigation.

Every input has an associated label with <label> , aria-label or aria-labelledby .

, or . Labels are close to related inputs

Fields of the same nature are grouped in <fieldset> tags (example: radios, checkboxes)

tags (example: radios, checkboxes) Every <fieldset> has a <legend>

has a Every choice input with options uses a <select> component (no custom selects!) or ARIA comboboxes.

component (no custom selects!) or ARIA comboboxes. Avoid using the autofocus attribute on inputs. Screen-readers jump straight into the input without any context about the form. The only valid way to use it is when it doesn't disrupt navigation: for instance, Google's search input on the landing page has it (because it is the only thing in the page) but not the one on the results page (which has way more content).

attribute on inputs. Screen-readers jump straight into the input without any context about the form. The only valid way to use it is when it doesn't disrupt navigation: for instance, Google's search input on the landing page has it (because it is the only thing in the page) but not the one on the results page (which has way more content). Forms with juridic or financial consequences (such as a checkout form) can be reviewed after the form has been validated and before the action is submitted

User info related fields have an autocomplete attribute configured. Read the docs on MDN about autocomplete.

Bad example: radio buttons should be placed inside a <fieldset> with a <legend> and radio inputs are not linked to their labels.

Dynamic content

Time limits can be controlled or disabled (refresh/redirect/session timeouts, other timeouts). Imagine a bank website automatically logging off users after 15 minutes or an event website selling tickets with a time limit in the checkout form. Some users wouldn't be able to navigate the website and use it in that amount of time.

No window is opened without the user's intervention

Every change of context (new window opens, focus is changed, page is changed) is triggered by a button, a submit input, a link or an element with a text warning in advance of the context change.

Rapid flashes (video, animations) must have a frequency of less than 3 per second or cover an area smaller than 21 824 pixels

Every animation lasts less than 5 seconds or can be stopped (slideshows for instance)

Every multitouch action can be triggered with single touch actions

Features requiring device movement have nonphysical alternatives (example: shake your phone to play a random tune). Exceptions: this criteria is irrelevant when an alternative is impossible: gyrometers, pedometers...

"Toaster" messages have a role="status" , role="alert" , role="log" or role="progressbar" attribute.

You can turn off animations if the user has opted-out of them with the prefers-reduced-motion setting.

Bad example: SpaceX Stats has countdowns, which update the text every second. Such a time-dependent content should use the ARIA timer role.

Bad example: this funny website to test your HTML knowledge is not accessible at all because many people will not be able to take the test in 112 seconds. One way to improve this would be to provide different levels of difficulty, the easiest being "no time limit".

Conclusion

I hope that this article helped you audit your website and understand what should be improved to make it more accessible. For me, it was a wake-up call that I needed to re-learn some of the web basics (such as proper HTML semantics). The web is transforming our society, its inclusiveness should be a default and not a bonus.

Sources and inspirations