Accessibility with React and Storybooks
What is web accessibility?
Accessibility in web development refers to making websites and web applications usable for all, including those with disabilities. This includes ensuring that their content is readable and understandable by assistive technologies such as screen readers and the user interface is navigable using keyboard controls rather than just a mouse.
Why accessibility?
Building accessible applications support inclusion for people with disabilities as well as others, such as older people, people in rural areas, and people in developing countries. Here is why you start building accessible applications:
When should you consider accessibility?
Accessibility isn't the first thing that comes to mind when building a product. In the early stages, you're busy trying to see if there is a product-market fit. As the product grows, you build features and capture market share. Yada yada yada.…
Most people think of accessibility as something that you do at a later stage to meet compliance. However, I beg to differ.
Accessibility should be included right from the start. But you don't need to do everything from the get-go. The most significant advantage is that your team is considering a broader user base. They're thinking about all kinds of users while building the product. A team like this can bring in a differentiator for your product.
Start with the basics:
This makes your web content and web application accessible to people with disabilities. With this, you are starting to comply with the laws and optimizing your application for better reach and usability.
As your product grows and you move to other phases of the startup journey, you should start covering complex cases such as support for assistive devices, screen readers, keyboard accessibility, and more.
Why Storybook for web accessibility?
Storybook is an open-source project that allows you to document, view and test your components and their variations in isolation. It comes with add-ons that help with viewport testing, unit testing, accessibility testing, and more.
The A11y addon for Storybook runs on top of the Axe Accessibility Engine developed by Deque Systems. This is the same engine used by Google Lighthouse to test and score web pages. A11y addon is a simple yet powerful tool.
Storybook's A11y helps you build your first line of QA defense to identify common accessibility issues like missing aria roles and attributes, color contrasts, etc. It also lets you catch regressions by integrating them into your test automation pipeline. This ensures all components at the time of merge passed the accessibility tests.
Here are some reasons why you should use Storybook's A11y addon:
How to include accessibility in your application?
1. Integrate to pinpoint component-level violations
The integration is straightforward if you’re already using Storybook to document and host your components in isolation. You’ll have to add @storybook/addon-a11y to the addons section in the storybook config file. That’s all, and the integration is done.
Installing the Storybook A11y addon
npm i -D @storybook/addon-a11y
(or)
yarn add -D @storybook/addon-a11y
Adding the a11y to the addons array in the .storybook/main.js file.
// .storybook/main.js
module.exports = {
...
addons: [
'@storybook/addon-a11y',
...
],
...
}
With this, you’ll be able to view the accessibility audits for all your components and their stories.
2. Write all possible stories for a Component in a user’s journey
Writing stories for a Component in a user’s journey and running accessibility audits against each of them is vital. This is when Storybook’s A11y addon starts doing wonders.
Let’s take a step back to understand something important. The page you view in your application combines components and variations. If we could test each component and all its variations, we would have successfully tested all the components in a user’s journey.
Let’s consider an example to understand this better. Let’s say you’re creating a Button component that would render a primary or secondary button based on the type prop passed to it. Let’s write stories for both of them as shown below:
Recommended by LinkedIn
const ButtonTemplate = (props) => ...;
export const PrimaryButton = ButtonTemplate.bind({});
PrimaryButton.args = {
type: 'primary',
};
SecondaryButton.args = {
type: 'secondary',
};
From the above screenshots, you’ll notice something really interesting. For the same Button component that renders primary and secondary buttons, the primary is accessible, whereas the secondary isn’t because of insufficient color contrasts. This is where writing and documenting all possible stories for a component becomes really important.
3. Automate to catch regressions
The changes made to a component can unintentionally introduce new accessibility issues. You'll want to test all your stories before opening a pull request to catch such regressions.
Storybook helps you integrate these accessibility tests into your test automation pipeline with the help of Storybook test runner and axe-playwright.
Install the test runner and related packages (note it requires Storybook 6.4 or above).
npm i -D jest @storybook/test-runner axe-playwright
(or)
yarn add -D jest @storybook/test-runner axe-playwright
Also, install playwright and its dependencies:
npx playwright install --with-deps
Add a new test-runner configuration file inside your Storybook directory.
// .storybook/test-runner.js
const { injectAxe, checkA11y } = require('axe-playwright');
module.exports = {
async preRender(page, context) {
await injectAxe(page);
},
async postRender(page, context) {
await checkA11y(page, '#root', {
detailedReport: true,
detailedReportOptions: {
html: true,
},
});
const accessibilityTree = await page.accessibility.snapshot();
expect(accessibilityTree).toMatchSnapshot();
},
};
The preRender hook helps to inject Axe into a story, while postRender runs accessibility tests post-render. Assistive devices like screen readers use the accessibility tree to parse your UI and convert it into speech. Snapshotting the accessibility tree helps you track the order in which they are parsed. It also helps to catch regressions as you update your components.
To run the tests, add a script for the test runner to your package.json. Also, ensure the script to run the storybook is present, as shown below.
{
"scripts": {
"storybook": "start-storybook -p 6006",
"test-storybook": "yarn test-storybook"
}
}
Run your storybook script in one terminal window with npm run storybook or yarn run storybook. Then run your test runner in another with npm run test-storybook or yarn run test-storybook.
This will help you automatically catch regression by running accessibility tests for all components, as shown in the image below.
How to use the A11y addon?
The A11y addon displays three tabs. They are violations, passes, and incompletions. Axe defines incomplete as a rule state that occurs when it cannot decide if a particular rule passes or fails. In such a case, it gathers information and provides it to the user to decide.
Within each tab, it displays rules that have met the criteria. Clicking the rule provides information along with a link containing in-depth information. A list of flagged elements by the selector path is also displayed under the rule information. In addition, a severity tag is attached to each element to indicate the urgency of fixes to be made.
The highlight results checkbox located to the right of each rule enables you to highlight flagged DOM elements in the Storybook canvas. This helps you identify the exact sections in the component that require fixes.
What A11y addon doesn’t do?
A11y addon is only a partial replacement for manual testing. A11y addon, or any other automated tool, will only catch a percentage of potential accessibility issues. Automated tools are most organizations’ first choice for scanning their web application for problems.
Automating the auditing will add efficiencies to our testing and provide an early warning system that can be run much more frequently than to perform manual testing. You’ll still have to test your components to make them completely accessible manually.
How to build a strong developer culture for accessibility?
Building a developer culture for accessibility can be challenging. Developers want to write code and push it as soon as possible. If it works for them, then they are of the assumption that it should work for everyone. Getting people to think of these cases and making them a part of the workflow requires a change in habit.
Here are a few pointers that worked for my team:
Conclusion
Building accessible applications can be overwhelming. Storybook’s A11y addon smoothens the process. Unlike other tools today, A11y does component-level accessibility testing. It provides feedback as you code. This results in a faster feedback loop. It also helps to integrate accessibility tests into your test automation pipeline. This helps test all your stories and catch regressions before raising a pull request. This makes sure that everyone on your team follows the required standards. In addition, it also provides emulators for visual testing. This helps you relate to users with disabilities in ways that wouldn’t have been possible before. Something to also note is that the A11y addon is not a complete replacement for manual testing. It catches only some potential accessibility issues and serves as a first line of defense in QA testing. You’ll still have to test your components to make them completely accessible manually.
Overall, it’s a fantastic tool and very useful compared to most.
This article was originally published on the Wednesday Solutions blog. Click on the button below 👇 to learn more about our design and development expertise.