(Last Updated on 6 December 2019)
Last week I was moaning about the fact that 63% of developers surveyed don’t test accessibility. And I was banging on about editing a ‘learn HTML’ book which was riddled with basic accessibility errors, when Frederik replied in order to shut my whining and make me do something about it:
Bruce, as a complete amateur it’s hard to collect this information from scattered sources. Is there some kind of compendium or comprehensive source? It’s only a personal website but it’s a matter of principle.
— Frederik Vanhoutte (@wblut) November 22, 2019
This isn’t a comprehensive guide to accessibility, but we’ll look at ways to avoid the most common accessibility errors identified by the WebAIM accessibility analysis of the top 1,000,000 home pages, and the HTTPArchive 2019 Web Almanac analysis of 5.8 million pages. I’m not going to get philosophical; if you’re reading this, I assume you care about why, and just want some tips on how. (But if you need to convince someone else, here’s the 4 minute business case for accessibility.)
Insufficient colour contrast
83% of homepages have low colour contrast. There are several ways to check this. I personally use Ada Rose Cannon’s handy Contrast Checker Widget, which sits in my bookmarks bar like a useful Clippy and goes through the current tab and highlights where there isn’t enough contrast. Or you can use Firefox’s Accessibility Inspector in the devtools to check and tweak the CSS until you get a pass. To check a particular combination of colours, contrastchecker will give you AA and AAA ratings. whocanuse.com will tell you which particular types of visual impairments may have difficulty with your chosen colours.
Missing alternative text for images
A whopping 68% of homepages had missing alt text (NOT alt tags). Every <img> must have alternate text. Here are basic rules:
- If the image is purely decorative, it must have empty alt text:
alt="". But it should probably be in CSS, anyway.
- If an image is described in body text it should have empty alt
alt="", to avoid repetition. But be careful if it’s an <img> in a <figure> (hat-tip to Mallory).
- If an image is the content of a link (for example, your organisation’s logo can be clicked to go to the homepage) the alternate text should describe the destination of the link. For example,
Heydon Pickering’s revenge.css bookmarklet does a quick and easy test to diagnose these, although I feel some of its other warnings are now outdated – I’ve filed an issue.
Empty links, empty buttons
I don’t know why anyone would do this, but apparently 58% of homepages tested had empty links, and 25% had empty buttons. I’m assuming this means they were empty of text, and contained only an image or an image of text. In the case of buttons, HTTPArchive Almanac says “often the reason this confusion occurs is due to the lack of a textual label. For example, a button displaying a left-pointing arrow icon to signify it’s the “Back” button, but containing no actual text”. (They found 75% of pages do this.) If that’s the case, the image needs alternate text that describes the function of the button or destination of the link. And don’t use icon fonts.
Use Heydon’s revenge.css bookmarklet to diagnose these.
Missing form input labels
52% of homepages had missing form labels. I prefer to wrap the label around its input like this:
<label>Email adddress: <input type="email" /> </label>
I find it’s more robust than associating a form with a label using the
for="id" pattern. If you can’t use an HTML
label element, you can label an input for assistive technology using
aria-label="useful instruction" or (less useful) a
title attribute on the
input. Use Heydon’s revenge.css bookmarklet to test these. WebAIM has more advanced form labelling techniques.
Missing document language
23% if homepages didn’t declare the human language of the document. This matters because (for instance) the word “six” is pronounced by a French screen reader very differently from an English screen reader. It’s simple to do:
<html lang="en"> tells assistive tech that the main language of this page is English. The codes are defined in BCP47.
Missing <main> elements
The HTTPArchive study of 5.8million pages shows that only 26% of pages have a <main> element and 8.06% of pages erroneously contained more than one main landmark, leaving these users guessing which landmark contains the actual main content.
Solution: wrap your main content, that is, stuff that isn’t header, primary navigation or footer, in a <main> element. All browsers allow you to style it, and assistive technologies know what to do with it.
Happily, more than 50% of pages use <nav> <footer> and <header>. In my opinion, <nav> should go around only your primary navigation (and can be nested inside <header> if that suits you). In its survey of screen reader users, WebAIM found that 26% of screen reader users frequently or always use these landmarks when navigating a page.
Here’s a YouTube video of blind screenreader user Leonie Watson talking through how she navigates this site using the HTML semantics we’ve discussed.
You can also make tagged accessible PDFs from your pages using Prince—it’s free for non-commercial use. If you’re one of the React Kool-Kidz™, I recommend using Tenon-UI: Tenon’s accessible React components library.
Buy me a pint when you see me next. xxx
The single source of truth is Web Content Accessibility Guidelines (WCAG) 2.1 from W3C. UK’s Government Digital Service has a good readable Understanding WCAG 2.1 guide. For advanced applications requiring ARIA, I find W3C’s Using ARIA invaluable.
You want tools? The BBC has open-sourced its BBC Accessibility Standards Checker. Google Lighthouse and Tenon.io are also very good. Please note that no automated tool can be completely reliable, as the fun article Building the most inaccessible site possible with a perfect Lighthouse score demonstrates.
If you want a self-paced course, on International Day of Persons with Disabilities, W3C launched an Introduction to Web Accessibility free online course in cooperation with UNESCO. Enrol now; the course starts 28 January 2020.