Making Sense Of WAI-ARIA: A Comprehensive Guide

This article is a sponsored by Fable

The Web Accessibility Initiative — Accessible Rich Internet Applications (WAI-ARIA) is a technical specification that provides direction on how to improve the accessibility of web applications. Where the Web Content Accessibility Guidelines (WCAG) focus more on static web content, WAI-ARIA focuses on making interactions more accessible.

Interactions on the web are notorious for being inaccessible and are often part of the most critical functions such as:

  • submitting a job application,
  • purchasing from an online store, or
  • booking a healthcare appointment.

I’m currently the Head of Accessibility Innovation at Fable, a company that connects organizations to people with disabilities for user research and accessibility testing and provides custom training for digital teams to gain the skills to build inclusive products.

As an instructor for accessible web development, I spend a lot of time examining the source code of websites and web apps and ARIA is one of the things I see developers misusing the most.

HTML

When you use HTML elements like input, select, and button, there are two things you’ll get for accessibility: information about the element is passed to the DOM (Document Object Model) and into an Accessibility Tree. Assistive technologies can access the nodes of the accessibility tree to understand:

  • what kind of element it is by checking its role, e.g., checkbox;
  • what state the element is in, e.g., checked/not checked;
  • the name of the element, e.g., “Sign up for our newsletter.”

The other thing you get when using HTML elements is keyboard interactivity. For example, a checkbox can be focused using the tab key and selected using the spacebar (specific interactions can vary by browser and operating system, but the point is they are available and standardized across all websites when you use HTML elements).

When you don’t use HTML, for example, if you build your own custom select using <div>s and <span>s or you use a component library, you need to do extra work to provide information about the element and build keyboard interactivity for assistive technology users. This is where ARIA comes into play.

ARIA

Accessible Rich Internet Applications (ARIA) include a set of roles and attributes that define ways to make web content and web applications more accessible to people with disabilities.

You can use ARIA to pass information to the accessibility tree. ARIA roles and attributes don’t include any keyboard interactivity. Adding role="button” to a <div> doesn’t make it respond when you press the Enter key — that you have to build using JavaScript or another language. However, the ARIA Authoring Practices Guide does include a list of what keyboard interactivity should be added to various components such as accordions, buttons, carousels, etc.

Roles

Let’s start with roles. What the heck is this thing in the code below?

<div className="dd-wrapper">
  <div className="dd-header">
    <div className="dd-header-title"></div>
  </div>
  <div className="dd-list">
    <button className="dd-list-item"></button>
    <button className="dd-list-item"></button>
    <button className="dd-list-item"></button>
  </div>
</div>

This is actually a snippet of code I found online from a select element for React. The fact that the element is completely unrecognizable from the code is exactly the issue that any assistive technology would have — it can’t tell the user what it is or how to interact with it because there’s no ARIA role.

Watch what we can do here:

<div className="dd-wrapper" role="listbox">

You might not be familiar with a listbox, but it’s a type of select that a screen reader user could recognize and know how to interact with. Now you could just use <select>, and you wouldn’t have to give it a role because it’s already got one that the DOM and accessibility tree will recognize, but I know that’s not always a feasible option.

A role tells an assistive technology user what the thing is, so make sure you use the correct role. A button is very different from a banner. Choose a role that matches the function of the component you’re building.

Another thing you should know about ARIA roles is that they override an HTML element’s inherent role.

<img role="button">

This is no longer an image but a button. There are very few reasons to do this, and unless you exactly knew what you’re doing and why, I’d stay away from overriding existing HTML roles. There are many other ways to achieve this that make more sense from accessibility and a code robustness perspective:

<button><img src="image.png" alt="Print" /></button> 
<input type="image" src="image.png" alt="Print" />
<button style="background: url(image.png)" />Print</button>

If you’re building a component, you can look up the pattern for that component in the ARIA Authoring Practices Guide which includes information on which role(s) to use. You can also look up all available roles in the mdn web docs.

In summary, if you’re building something that doesn’t have a semantic HTML tag that describes it (i.e., anything interactive built using <div> or <span>), it needs to have an ARIA role so that assistive technology can recognize what it is.

States And Properties (Aka ARIA Attributes)

In addition to knowing what an element is, if it has a state (e.g., hidden, disabled, invalid, readonly, selected, and so on) or changes state (e.g., checked/not checked, open/closed, and so on), you need to tell assistive technology users what its current state is and its new state whenever it changes. You can also share certain properties of an element. The difference between states and properties isn’t really clear or important, so let’s just call them attributes.

Here are some of the most common ARIA attributes you might need to use:

  • aria-checked
    It’s used with ="true" or ="false" to indicate if checkboxes and radio buttons are currently checked or not.
  • aria-current
    It’s used with ="true" or ="false" to indicate the current page within breadcrumbs or pagination.
  • aria-describedby
    It’s used with the id of an element to add more information to a form field in addition to its label. aria-describedby can be used to give examples of the required format for a field, for example, a date, or to add an error message to a form field.
<label for="birthday">Birthday</label>
<input type="text" id="birthday" aria-describedby="date-format">
<span id="date-format">MM-DD-YYYY</span>
  • aria-expanded
    It’s used with ="true" or ="false" to indicate if pressing a button will show more content. Examples include accordions and navigation items with submenus.
<button aria-expanded="false">Products</button>

This indicates that the Products menu will open a submenu (for example, of different product categories). If you were to code it like this:

<a href="/products/">Products</a>

You’re setting the expectation that it’s a link, and clicking it will go to a new page. If it’s not going to go to a new page, but it actually stays on the same page but opens a submenu, that’s what button plus aria-expanded says to an assistive technology user. That simple difference between <button> and <a> and the addition of aria-expanded communicates so much about how to interact with elements and what will happen when you do.

  • aria-hidden
    It’s used with ="true" or ="false" to hide something that is visible, but you don’t want assistive technology users to know about it. Use it with extreme caution as there are very few cases where you don’t want equivalent information to be presented.

One interesting use case I’ve seen is a card with both an image and the text title of the card linking to the same page but structured as two separate links. Imagine many of these cards on a page. For a screen reader user, they’d hear every link read out twice. So the image links used aria-hidden="true". The ideal way to solve this is to combine the links into one that has both an image and the text title, but real-life coding isn’t always ideal, and you don’t always have that level of control.

Note that this breaks the fourth rule of ARIA (which we’ll get to in a bit), but it does it in a way that doesn’t break accessibility. Use it with extreme caution when there are no better workarounds, and you’ve tested it with assistive technology users.

  • aria-required
    It’s used with ="true" or ="false" to indicate if a form element has to be filled out before the form can be submitted.

If you’re building a component, you can look up the attributes for that component on the ARIA Authoring Practices Guide. The mdn web docs covers states and properties as well as ARIA roles.

Keep in mind that all these ARIA attributes tell a user something, but you still have to code the thing you’re telling them. aria-checked="true" doesn’t actually check a checkbox; it just tells the user the checkbox is checked, so that better be true or you’ll make things worse and not better for accessibility. The exception would be aria-hidden="true" which removes an element from the accessibility tree, effectively hiding it from anyone using assistive technology who can’t see.

So now we know how to use ARIA to explain what something is, what state it’s in, and what properties it has. The last thing I’ll cover is focus management.

Focus Management

Anything interactive on a website or web app must be able to receive focus. Not everyone will use a mouse, trackpad, or touch screen to interact with sites. Many people use their keyboard or an assistive technology device that emulates a keyboard. This means that for everything you can click on, you should also be able to use the tab key or arrow keys to reach it and the Enter key, and sometimes the spacebar, to select it.

There are three concepts you’ll need to consider if you use <div> and <span> to create interactive elements:

  1. You need to add tabindex="0" so that a keyboard or emulator can focus on them.
  2. For anything that accepts keyboard input, you need to add an event listener to listen for key presses.
  3. You need to add the appropriate role so that a screen reader user can identify what element you’ve built.

Remember that native HTML controls already accept keyboard focus and input and have inherent roles. This is just what you need to do when creating custom elements from non-semantic HTML.

Ben Myers does a deep dive into turning a div into a button, and I’ll share parts of his example here. Notice the tabindex and the role:

<div tabindex="0" role="button" onclick="doSomething();">
    Click me!
</div>

And you’ll need JavaScript to listen to the key presses:

const ENTER = 13;
const SPACE = 32;
// Select your button and store it in ‘myButton’
myButton.addEventListener('keydown', function(event) {
    if (event.keyCode === ENTER || event.keyCode === SPACE) {
        event.preventDefault(); // Prevents unintentional form submissions, page scrollings, the like
        doSomething(event);
    }
});

When it comes to figuring out which keys to listen for, I suggest looking up the component you’re building in the ARIA Authoring Practices Guide and following the keyboard interaction recommendations.

Common Mistakes

Having looked at a lot of code in my lifetime, I see some accessibility errors being made repeatedly. Here’s a list of the most common mistakes I find and how to avoid them:

Using An aria-labelledby Attribute That References An ID That Doesn’t Exist

For example, a modal that has a title in the modal but aria-labelledby is referencing something else that no longer exists. It’s probably something removed by another developer who didn’t realize the aria-labelledby connection was there. Instead, the modal title could’ve been an <h1> and either aria-labelledby could reference the <h1> or you could set the focus on the <h1> when the modal opens and a screen reader user would know what’s going on as long as role="dialog” was also used. Try to avoid fragile structures that, if someone else came along and edited the code, would break easily.

Not Moving The Focus Into The Modal When It Opens

Countless times I’ve seen a screen reader user navigating the page behind the modal either unaware a modal has opened or confused because they can’t find the contents of the modal. There are several ways to trap focus within a modal, but one of the newer methods is to add inert to the <main> landmark (and, of course, make sure the modal isn’t inside <main>). Inert is getting better support across browsers lately. To learn more, check out Lars Magnus Klavenes’ Accessible modal dialogs using inert.

Adding Roles That Duplicate HTML

In general, doing something like this <button role="button”> is pointless. There is one case where it might make sense to do this. VoiceOver and Safari remove list element semantics when list-style: none is used. This was done on purpose because if there is no indication to a sighted user that the content is a list, why tell a screen reader user that it’s a list? If you want to override this, you can add an explicit ARIA role="list" to the <ul>.

Adrian Roselli says an unstyled list not being announced as a list “…may not be a big deal unless user testing says you really need a list.” I agree with him on that point, but I’m sharing the fix in case your user testing shows it’s beneficial.

Adding tabindex="0" To Every Element

Sometimes developers start using a screen reader and assume that tabbing is the only way to navigate; therefore, anything without tabindex isn’t accessible. This is NOT true. Remember, if you don’t know how to use a screen reader, you can’t troubleshoot usability issues. Meet with an everyday screen reader user to figure those out.

Using Child Roles Without Parent Roles

For example, role="option" must have a direct parent with role="listbox".

<div role="listbox">
    <ul>
      <li role="option">

The above code isn’t valid because there’s a <ul> between the parent and child elements. This can be fixed by adding a presentation role to essentially hide the <ul> from the accessibility tree, like <ul role="presentation”>.

Using role="menu" For Navigation

Website navigation is really a table of contents and not a menu. ARIA menus are not meant to be used for navigation but application behavior like the menus in a desktop application. Instead, use <nav>, and if you have child navigation links, those should be hidden until a button is pressed to show them:

<nav aria-label="Main menu">
    <button aria-expanded="false">Products</button>
    <ul hidden>
       <li>Cat pyjamas</li>...

If you want to learn more, Heydon Pickering does a deep dive into Building Accessible Menu Systems in his Smashing Magazine article.

Regarding navigation, using <nav> more than once on a page without giving each instance a unique label means that screen reader users will have to explore each navigation region to find the one they’re looking for. A simple aria-label on each <nav> will make it much easier.

<nav aria-label="Customer service">
  <ul>
    <li><a href="#">Help</a></li>
    <li><a href="#">Order tracking</a></li>
    <li><a href="#">Shipping & Delivery</a></li>
    <li><a href="#">Returns</a></li>
    <li><a href="#">Contact us</a></li>
    <li><a href="#">Find a store</a></li>
  </ul>
</nav>
How To Validate ARIA

Use automated accessibility checkers like Axe or WAVE extensions when you run your code in a browser. Accessibility linters like Axe for Visual Studio Code or ESLint for JSX elements will check your code as you write it.

Listen to your code with a screen reader. You’d never ship code without running it in a browser to make sure it works, and using a screen reader can be the same kind of check. NVDA is free for Windows, and VoiceOver comes built into Macs and iPhones. TalkBack is built into Android phones.

Test with assistive technology users. I consider this mandatory for any large organization that has a budget for accessibility (and they all should). There are companies that can recruit assistive technology users for testing or run user testing for you, and the company I work for can provide 2-day turnarounds on user testing that is facilitated by you or unmoderated to support accessibility testing at scale.

Frameworks And Component Libraries

If you’re using a web framework, one way to make the lift of building for accessibility a bit lighter is to use a component library with accessibility built in. I’ll add the caveat that accessibility can be complex and not everything that claims to be accessible is truly usable by assistive technology users. The best way to ensure accessibility is to always test with the users you are building for.

Here are some starting points for your search:

Conclusion

Hopefully, this has demystified ARIA for you. Like a secret language that only the most elite accessibility geeks know, it has its own Fight Club-esque rules.

  1. The first rule of ARIA is “Don’t use ARIA.” A <button> will always be better than <div role="button">.
  2. Secondly, don’t override native semantics. Instead of <button role="heading">, use <h3><button>.
  3. Also, always remember that all ARIA interactive elements must work with the keyboard.
  4. Don’t use role="presentation" or aria-hidden="true" on a focusable element. <button role="presentation”> means you’re hiding that button only from assistive technology users. That’s not just inaccessible; it’s outright excluding certain users.
  5. Last but not least, all interactive elements must have an accessible name. There are many ways to do that, and here are some of them:
<button>Print</button> (the name is the button text)

<div aria-label="Settings"><svg></div> (the aria-label assigns a name)

<div aria-labelledby="myName">
  <h1 id="myName">Heading</h1>
</div>

<label for="name">Name</label>
<input type="text" id="name" />

I like to think of ARIA as a tool used by the most elite Special Ops Team that you call in for your most difficult accessibility challenges. Well, maybe I just always wanted to do one-arm pushups like Emily Blunt in Edge of Tomorrow, and this is the closest I can get. Anyhow, I hope this was helpful and that you are no longer confused about ARIA. Go forth and build accessible things!

A Complete Guide To Accessibility Tooling

Learning to build accessible websites can be a daunting task for those who are just starting to implement accessible practices. We’ve pulled together a wide range of accessibility tooling, ranging from single-use bookmarklets to full-blown applications, in order to help you get started with building more accessible websites.

ARIA

The WebAIM Million survey found that home pages with ARIA present averaged 41% more detectable errors than those without ARIA. ARIA is an essential tool for creating complex web applications, but the specification is strict and can be tricky to debug by those who do not use assistive technology regularly. Tooling can help us ensure that we are using ARIA correctly and not introducing more errors to our applications.

The Paciello Group has created a WAI-ARIA bookmarklet which scans your page to make sure all elements and their given roles and ARIA attributes are valid. Upon activating the bookmarklet, the page is scanned for any errors, and a new tab will be opened with the results. The results include the total number of valid roles, any detected ARIA errors, and code snippets of where any errors were found so that you can easily debug your page.

One thing not explicitly tested in the above bookmarklet is the presence of duplicate ARIA roles. Certain landmark roles have names that sound like they might apply to several elements, but should only be used once per page, such as banner or contentinfo. Adrian Roselli has come up with a simple CSS-based bookmarklet to check if any of these ARIA roles have been duplicated. Activating the bookmarklet will add a red outline to any offending element.

NerdeRegion is a Chrome extension that logs all the output of any aria-live regions. Can’t figure out why your screen reader is announcing something unexpectedly? NerdeRegion can let you keep track of timestamped announcements and the source element they originate from, all within a panel in DevTools. Since there can be bugs and inconsistencies with how aria-live regions are announced with different screen readers, NerdeRegion can be a great tool to figure out if an issue is potentially caused by your code or by the device combination.

Automatic Testing Tools

This class of tools can be used by the developer or tester to run automated tests on the output of your code, catching errors that may not appear obvious in the source code. There are many high-quality paid services and other tools beyond what we’ve mentioned here, but we’ve focused on tools with comprehensive free offerings in order to reduce barriers to entry. All of the listed tools can be run on pages that are not on the public internet, allowing them to be more easily incorporated into a development flow. It is important to note that accessibility testing is complicated and always requires manual testing to understand the full context of the site, but these automated testing tools can give you a solid head start.

A lot of tools use axe-core under the hood, so it may be redundant to use a combination of tools. Ultimately, what kind of tool you choose is more about what kind of UI you prefer, and the level of comprehensiveness in the results. For example, Lighthouse, the tool built into Google Chrome, uses a partial selection of axe-core rules, so if you manage to get a clean scan with axe DevTools, you shouldn’t need to run a Lighthouse scan as well.

Axe DevTools is available as a Chrome or Firefox browser extension and shows up as a panel in the developer tools. You can test a whole page or just part of a page, and all detected issues are sorted by severity and come with code snippets for easier debugging. Axe also lets you catch more errors than other automated tools with its Intelligent Guided Tests feature. Intelligent Guided Tests identify areas to test and do as much heavy lifting as possible, before asking the tester questions in order to generate a result. Axe also allows you to save and export results, which is useful for working through fixing errors as part of a longer and more cooperative development process.

Accessibility Insights also runs on axe-core, but has several features that differentiate it from axe DevTools. It can be run on various platforms, including Android, Windows, or as a browser extension. All versions of Accessibility Insights feature an inspector-like tool for looking up individual element information, as well as a way of running automated checks. The web extension also contains an Assessment feature, which has a combination of automated, guided and manual tests in order to allow you to generate a full report.

WAVE by WebAIM has been an integral part of my tool kit. Available in extension form as well as a mass testing service and an API, I find this tool best for checking my work as I develop due to its simplicity and speed. Everything is loaded as a panel on the side of your page, and you can get a holistic view of errors by scrolling through the page. If an error is displayed in the side panel but you aren’t sure where in the DOM it is, you can turn off styles to locate it within the markup. WAVE’s heading and landmark feature is one of my favorite things about it as it ensures that my document semantics are correct as I build.

SiteImprove has a free Chrome extension in addition to their paid service offerings. Like WAVE, you run the extension on a page and it lists errors in a panel on the side of the page, including filters for things like conformance level, severity and responsibility. The severity filter is especially useful as automatic testing always tends to produce some false positives.

Colors

Low contrast text errors were found on a whopping 86.4% of homepages last year. Developers often have limited control over a color palette, so it is important to try to establish an accessible color palette as early on in the process as possible.

When you’re starting to design a color palette, an in-browser color picking tool may be helpful. Are My Colors Accessible is a tool that can help you figure out an accessible color palette. The basic mode calculates the contrast ratio between any two colors. The font size and font weight of your text can affect the contrast ratio required based on the level of conformance, and this tool helpfully lays out all the different standards it meets. It also features HSL range sliders so that you can tweak any of the colors, with the results automatically updating as you make adjustments. Palette mode lets you compare every color in a palette against each other and displays the contrast ratio and standards met, which is helpful for determining how you can combine different colors together. Making any color adjustments also updates the permalink, allowing you to easily share color combinations with your team. If you prefer a different interface for selecting colors, Atul Varma has built a similar tool that uses a color picker instead of HSL range sliders.

Geenes attempts to do it all by building out full tint/shade ranges for each color group you add, allowing you to design a full-color system instead of a limited palette. In addition to providing contrast ratios, Geenes also allows you to apply your palette to various mockups, and emulate different forms of color blindness. You can trial most features for free, and unlock multiple palettes with a donation.

Certain tools can help you solve specific color-related accessibility issues. Buttons in particular can be tricky, as not only do you have to worry about the text color with the background color, you also need to consider the button background with the page background, and the focus outline color with both backgrounds. Stephanie Eckles’s project ButtonBuddy explains these requirements in simple language and helps you pick colors for these individual parts.

Some color combinations may technically meet contrast requirements when viewed by people without color blindness but could pose problems for specific kinds of color blindness and low vision. Who Can Use applies a visual filter to emulate different types of color blindness and then calculates an approximate color contrast ratio.

If you would like to test your color combinations in the context of an existing site, Stark is a color picker extension for Chrome that lets you simulate certain kinds of color blindness. Additionally, Anna Monus has created a helpful writeup of color blindness tools already built into Chrome. While this kind of emulation can never fully replace testing with real users, it can help us make better initial choices.

Sometimes as developers, we start working on a project where we may need to design as we go and begin writing code without a full, pre-established brand palette. Once development has started, it can be tedious to keep importing color palettes back and forth into external tooling. There are many options for checking color contrast within a code environment. Alex Clapperton has developed a CLI tool where you pass in two colors and it outputs the contrast ratio and passing standards right in the terminal. The BBC has published a JavaScript color contrast checker that takes two colors and determines whether or not it meets your desired standard. A tool like this can live in your codebase with your tests, or be implemented in your design system library like Storybook, PatternLab, and so on.

A11y Color Tokens takes it a step further and lets you automatically generate complementary color tokens in CSS or SASS. You pass in a color and desired ratio to generate a shade or tint of that color that meets requirements. If you need to quickly check the contrast ratio of something, Chrome and Firefox now show the color contrast information within their respective developer tools color selectors as well. If none of these tools suit your fancy, Stephanie Walter has covered many other color-related tool options in her blog post on color accessibility.

Compatibility

Building for assistive technology can often add another level of complexity when it comes to debugging. Because assistive technology is essentially another layer of an interface on top of the browser, we now need to concern ourselves with combinations of browser and assistive technology. A bug may be present in either the browser or the assistive technology, or it may be present only in a particular combination. It’s a good idea to keep this list of bug trackers on hand when trying to fix a specific issue. Some of these are public so that you can see if others experience the bug you are having, but others only offer a means to report bugs in private.

Not all browsers and screen reader combinations work well together, and not all accessibility features are equally supported across browsers. These tools can help you check if you are experiencing a bug on a specific combination of devices. HTML5 Accessibility is a list of newer HTML features and whether or not the default browser implementation is accessibly supported. In a similar vein, Accessibility Support provides a list of ARIA roles and their support in the most popular browser and screen reader combinations.

Focus Management

Managing focus is a necessary but often difficult part of making complex applications accessible. We need to consider that the focus order is logical, that focus is moved around correctly on any custom components, and that each interactable element has a clear focus style.

This bookmarklet by Level Access labels every focusable element on the page, so that you can check that the focus order matches the reading order. For the Firefox users out there, Firefox’s Accessibility Inspector has added this feature since version 84.

In complex codebases, where different components or third-party code might be moving focus around unexpectedly, this little snippet by Scott Vinkle can help you see what element currently has focus. If I’m struggling with the focus being moved around by other parts of my application, sometimes I also like to replace console.log with console.trace to determine exactly what function is moving the focus around.

In order to test all focus styles on a web page, we can use Scott O’Hara’s script as a starting point. Tabbing through every element can get cumbersome after a while, so a script to rotate through each element can help us make sure our focus styles look consistent and work within the context of the page.

Setting a positive tabindex to try and fix the focus order is a common accessibility gotcha. Elements that have a positive tabindex will force the browser to tab to them first. While this may not technically be an error, this is often unexpected and can cause more problems than it solves. Paul J. Adam’s tabindex bookmarklet allows you to highlight all elements that have the tabindex attribute applied.

Layout Usability

The document reading order can sometimes fall out of sync with what a viewer might expect if a layout relies too heavily on the CSS Grid or Flexbox order property. Adrian Roselli has coded up a bookmarklet for keeping track of the reading order to help you make sure your site passes the meaningful sequence guideline.

The WCAG contains a text spacing criterion where all content should still work when certain text settings are applied. To test for this, Steve Faulkner has created a bookmarklet that automatically applies the required text spacing settings to all the text on a page. Avoiding things like fixed heights and allowing for overflow not only makes your site more accessible, it ensures that whatever content you put into your site won’t break the layout, something your content editors will thank you for.

Jared Smith built a bookmarklet to turn your cursor into a 44×44 pixel box so that you can hover it over your controls to make sure that they meet the recommended target size criterion.

Linters

Linters are a class of tools that catch errors by scanning the source code before the application is run or built. By using linters, we can fix smaller bugs before we even run or build the code, saving valuable QA time later.

Many developers already know and use ESLint in some capacity. Instead of learning new tooling, it’s possible to get a head start on your accessibility testing by including a new plugin into your existing workflow. Eslint-plugin-jsx-a11y is an ESLint plugin for your JSX elements, where any errors will be shown as you write your code. Scott Vinkle has written up a helpful guide on setting it up.

Deque has come out with axe Linter, available as a Github app or VS Code Extension. Axe Linter checks React, Vue, HTML and Markdown files against core rules without any configuration so it is easy to get up and running, although you are welcome to pass in your own options. One helpful feature is that it distinguishes between WCAG 2 and WCAG 2.1 which is useful if you are trying to meet a specific standard.

Markup

The web is built to be resilient. If you have broken markup, the browser will try its best to patch over any mistake. However, this can have unintended side effects, both from a styling perspective and an accessibility standpoint. Running your output through the W3C HTML validator can help catch things like broken tags, attributes being applied to elements that shouldn’t have them, and other HTML errors. Deque has created a W3C HTML Validator bookmarklet based on the same engine which lets you check the markup on localhost or password-protected pages that the regular validator cannot reach.

If you’re more of a visual person, Gaël Poupard’s project a11y.css is a stylesheet that checks for possible risks within your markup. Available in both extension or bookmarklet format, you can customize the language as well as the level of advice displayed. In a similar vein, sa11y is a tool that can be installed as a bookmarklet or integrated into your codebase. Sa11y is specifically designed for looking at the output of CMS content. It displays any warnings in non-technical language so that content editors can understand and make the necessary corrections.

Reading Level

An accessible site starts with accessible content. Cognitive accessibility has been a major focus of the ongoing WCAG 3 draft and is currently mentioned in Success Criterion 3.1.5, which suggests that authors aim for content to be understandable by a lower secondary (7-9th grade) reading level.

The Hemingway Editor calculates the reading level of your content as you write it, so that you can edit to make sure it is easily understandable. The panel on the side offers suggestions for how you can improve your content to make it more readable. If your site has already been published, Juicy Studio has produced a readability tool where you pass in a URL to the provided form and your site’s content is analyzed and graded using three different reading level algorithms. There is also a helpful explanation as to what each of these scores entails. However, one limitation of this particular tool is that it takes into account all the text rendered on the page, including things like navigation and footer text, which may skew the results.

Test Suites And Continuous Integration

The downside of most automated testing tools is that they require people to run them in the browser. If you are working on a single large codebase, you can incorporate accessibility testing into your existing testing process or as part of your continuous integration flow. When you write custom tests, you have an awareness of your application that automated testing tools don’t have, allowing you to perform customized, comprehensive testing in a more scalable way.

Once again, axe-core pops up as an open-source library that frequently underpins most of these tools, so whether or not a tool works for you will likely be based on how well it integrates with your code rather than any differences in testing results. Marcy Sutton has published a framework-agnostic guide for getting started writing automated tests for accessibility. She covers the difference between unit tests and integration tests and why you might want to choose one over the other in different scenarios.

If you already have a test framework that you enjoy, there’s a high chance that there is already a library that incorporates axe-core into it. For example, Josh McClure has written up a guide that uses cypress-axe, and Nick Colley has produced a Jest flavored version in jest-axe.

Pa11y is a tool that provides a configurable interface around testing that is also available in a CI version as well. Its many configuration options can let you solve complex issues that can come up with testing. For example, the actions feature lets you pass an array of actions before running the tests and can be useful for testing screens that require authentication before accessing the page.

User Preferences

There are many new media queries to help detect the user’s operating system and browser preferences. These days, developers are often detecting these settings in order to set the default for things like motion preferences and dark mode, but this may also lead to bugs that are difficult to reproduce if you do not have the same settings.

Magica11y is a set of functions that lets you determine your users’ preferences. Send the documentation page to non-technical testers or incorporate these into your app so that you can reproduce your user’s environments more accurately.

Wrapping Up

It’s estimated that automated accessibility testing can only catch 30% of all accessibility errors. Even as tooling continues to improve, it will never replace including disabled people in your design and development process. A sustainable and holistic accessibility process might involve having the whole team use tooling to catch as many of these errors as possible early on in the process, instead of leaving it all for testers and disabled users to find and report these issues later.

Need even more tooling? The A11y Project and Stark have curated lists of additional accessibility tools for both developers and users! Or feel free to leave any suggestions in the comments below, we’d love to hear what tools you incorporate into your workflow.

Collective #639


Radicle

A peer-to-peer stack for building software together. Without central servers and censorship.

Check it out



Mannequin.js

Mannequin.js is a simple library of an articulated mannequin figure. The shape of the figure and its movements are done purely in JavaScript. The graphics is implemented in Three.js.

Check it out



Cssfox

A place to showcase websites, receive web design awards, find inspiration for a web design project and interact with people that have similar interests.

Check it out


Advent of Code 2020

A new edition of the great coding Advent calendar: Advent of Code is an Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

Check it out







Exophysics

Explore the physics of other universes with this particle simulator that was built in ~500 lines of self-contained HTML/JS/WebGL2.

Check it out






An ex-Googler’s guide to dev tools

After leaving Google, many engineers miss the developer tools. Here’s one ex-Googler’s guide to navigating the dev tools landscape outside of Google, finding the ones that fill the gaps you’re feeling, and introducing these to your new team.

Read it


Arokite

Preview your business cards in a 3D scene you can customize, save and export.

Check it out





The post Collective #639 appeared first on Codrops.

Collective #590


Understanding Map and Set in JavaScript

Tania Rascia goes over the Map and Set objects, what makes them similar or different to Objects and Arrays, the properties and methods available to them, and examples of some practical uses.

Read it






Flight

3D video game experiments built with Three.js, TypeScript, React, Redux and GLSL shaders.

Check it out





Stage.js

In case you didn’t know about it: Stage.js is a 2D JavaScript library for cross-platform HTML5 game development.

Check it out




Google Fonts Tip

Addy Osmani shows how to shave up to 90% off the size of Google Fonts requests by declaring only characters you need with &text.

Check it out


Whoosh

A great game prototype by Charlie Gerard where you control a 3D spaceship with hand movements.

Check it out







Collective #590 was written by Pedro Botelho and published on Codrops.

Multi-Million Dollar HTML

Two stories:

  • Jason Grigsby finds Chipotle's online ordering form makes use of an input-masking technique that chops up a credit card expiration year making it invalid and thus denying the order. If pattern="\d\d" maxlength="2" was used instead (native browser feature), the browser is smart enough to do the right thing and not deny the order. Scratchpad math, based on published data, makes that worth $4.4 million dollars.
  • Adrian Roselli recalls an all-too-common form accessibility fail of missing a for/id attribute on labels and inputs results in an unusable experience and a scratchpad math loss of $18 million dollars to campaigns.

The label/input attribution thing really gets me. I feel like that's an extremely basic bit of HTML knowledge that benefits both accessibility and general UX. It's part of every HTML curriculum I've ever seen, and regularly pointed at as something you need to get right. And never a week goes by I don't find some production website not doing it.

We can do this everyone!

<label for="name">Name:</label>
<input id="name" name="name" type="text">

<!-- or -->

<label>
  Name:
  <input name="name" type="text">
</label>

The post Multi-Million Dollar HTML appeared first on CSS-Tricks.