The web is the greatest information dissemination tool in the history of the world. Basically, it’s the Library of Alexandria times a million, in your pocket.
It’s critical to every piece of everyday life, from your commute to your job to your dinner.
But what if you couldn’t use the internet? Or if parts of it were unavailable to you?
That’s why website accessibility is so important.
Website accessibility isn’t just a set of standards or guidelines. It’s not just about “ADA compliance” or not getting sued. It’s about making your online work – the stuff you poured your heart and soul into – available to everyone. In short, it’s the right thing to do.
Here’s what you need to know about accessibility, how to check your site, and specific things to watch out for.
101 Guide to Website Accessibility
The standard in accessibility guidelines is the Web Content Accessibility Guidelines (WCAG), version 2.1.
WCAG 2.1 is pretty huge, but it boils down to one acronym: POUR. That is, content must be:
It’s not just about being OK for screen reader software, or having enough color contrast, or making your layout easy to follow. It’s all of that.
There are multiple levels of accessibility standards: A, AA and AAA. They’re progressively more stringent – each has more rules than the last.
It’s not possible to “partially” meet a WCAG level. You either do or you don’t. For most sites, we recommend shooting for AA compliance.
Checking Your WCAG Compliance
Lighthouse is an open source tool provided by Google meant to help developers improve user experience on their web properties. It’s broken down into four scores, which are likely fed into the Google algorithm. (Yes, accessibility can impact SEO.) The one you need to think about here is, naturally, Accessibility.
To check your site’s accessibility, head to web.dev/measure, enter your URL and click “Run Audit.” The second score is the one to look for. It’s on a 1-100 scale. Most sites end up in the 60s or 70s out of the box; a select few – those that have focused on accessibility – are in the green, or 90+.
WCAG 2.1 Compliance Checklist
Lighthouse checks 35 individual website accessibility factors, and recommends a manual check of 11 more. Here they are.
- Background and foreground colors have a sufficient contrast ratio. We’ve written a whole article about this one. Basically, you’re shooting for a 4.5:1 contrast ratio for body text, and 3:1 for large or bold text. This is the most important one for designers, and probably the most commonly missed. (We’ve been guilty of that, but we’re fixing it!)
- [id] attributes on the page are unique. Screen readers and other assistive technologies need to be able to tell layout items apart. The HTML id= value can’t be repeated on a page.
- <frame> or <iframe> elements have a title. You need to tell screen readers what’s in your iframe with a descriptive and unique title element.
- Links have a discernible name. Link actual descriptive text, not a decorative element or something like “learn more.” (In fact, never use “learn more” if you can help it. It’s lazy.)
- The page contains a heading, skip link, or landmark region. Screen readers need to be able to easily bypass your header.
- Document has a <title> element. Tell screen readers and other assistive technologies what a pageis about with a descriptive title element. (This is also good for SEO.)
- <html> element has a [lang] attribute. Declare obviously what language your page is in. This ensures correct pronunciation in screen readers.
- <html> element has a valid value for its [lang] attribute. You need to use BCP 47-accepted language codes in your [lang] attribute. (en, not eng.)
- Image elements have [alt] attributes. Describe your images in code. Some developers leave out alt tags for purely decorative images. We’d prefer they be included.
- Lists contain only <li> elements and script supporting elements (<script> and <template>). List items and supporting script and template elements only in your ordered and unordered lists, please. No nested P or H tags.
- List items (<li>) are contained within <ul> or <ol> parent elements. Assistive technologies can’t parse bullet points or numbered elements if they’re not in a proper list.
- [user-scalable=”no”] is not used in the <meta name=”viewport”> element and the [maximum-scale] attribute is not less than 5. Let uses zoom in on your content as much as they need to.
- [accesskey] values are unique. Users need to be able to focus quickly on areas of a page. Don’t repeat accesskey values, if you use them.
- [aria-*] attributes match their roles. Use proper ARIA declarations to say what any custom controls on your page do. This is pretty rare.
- [role]s have all required [aria-*] attributes. Similar to the last one, use proper ARIA declarations to say what any custom controls on your page do. Again, pretty rare.
- Elements with an ARIA [role] that require children to contain a specific [role] have all required children. Similar to the last two, and again, pretty rare.
- [role]s are contained by their required parent element. Another ARIA role one. Pretty rare.
- [role] values are valid. Last one on ARIA roles. Pay attention to these, obviously, if you’re using custom control elements.
- [aria-*] attributes have valid values. There’s a certain syntax to ARIA attributes. Like [lang], use it.
- [aria-*] attributes are valid and not misspelled. Same as the last one.
- <audio> elements contain a <track> element with [kind=”captions”]. Provide metadata on captions for users with hearing impairments.
- <video> elements contain a <track> element with [kind=”captions”]. Same as above. Provide metadata on captions for users with hearing impairments.
- <video> elements contain a <track> element with [kind=”description”]. Provide audio descriptions of visuals in a video, such as facial expressions.
- Buttons have an accessible name. Give screen readers information on what a button does.
- <dl>’s contain only properly-ordered <dt> and <dd> groups, <script> or <template> elements. If you use definition lists, mark them up properly for screen readers.
- Definition list items are wrapped in <dl> elements. Same as the last one.
- <input type=”image”> elements have [alt] text. Use code to say what your images are.
- Form elements have associated labels. Allow screen readers to properly guide users in forms.
- Presentational <table> elements avoid using <th>, <caption> or the [summary] attribute. Only use <th>, <caption> and [summary] if you’re presenting tabular data in a table. Ideally, get rid of tables used for styling altogether.
- The document does not use <meta http-equiv=”refresh”>. Don’t refresh pages automatically.
- <object> elements have [alt] text. Use code to declare what non-text objects on your page are.
- No element has a [tabindex] value greater than 0. This confuses assistive technologies.
- Cells in a <table> element that use the [headers] attribute refer to table cells within the same table. Make sure your table headers and data cells match up.
- <th> elements and elements with [role=”columnheader”/”rowheader”] have data cells they describe. Make it easy for screen readers to navigate your table data.
- [lang] attributes have a valid value. Use a BCP 47 language code in your [lang] declaration. Don’t make up your own.
Manual Website Accessibility Checks
Lighthouse advises you to look at these 11 website accessibility factors, but cannot check them automatically.
- The page has a logical tab order. If you use the tab key to navigate your page, does it follow the expected order of things?
- Interactive controls are keyboard focusable. You should be able to tab to any control on the page (e.g., links) and activate them with the enter or return key.
- Interactive elements indicate their purpose and state. It should be obvious when buttons, links, etc., are active or capable of being used.
- The user’s focus is directed to new content added to the page. If something happens on a page, it should be obvious to the user.
- Custom controls have associated labels. Custom controls, like menus in <div>s, need to be accessible via keyboard controls.
- Custom controls have ARIA roles. Declare the purpose and state of all custom controls using proper ARIA syntax.
- Visual order on the page follows DOM order. Users should be able to tab through a page in a logical order.
- Offscreen content is hidden from assistive technology. Only relevant parts of a page should be accessible to screen readers.
- Headings don’t skip levels. Use H tags in numerical order. Put one H1 at the top of each page, use H2 as your main subhead, H3 below that, and so forth. Try not to use H tags as styling elements.
- HTML5 landmark elements are used to improve navigation. <main>, <nav> and <aside> give screen readers an easy way to jump to important parts of the page.