View all articles
Accessibility with React and Storybooks
February 16, 2023
Praveen Kumar
Tech Lead

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:

  1. You get more customers - According to the WHO, 15% of the world’s population has some disability. That’s more than a billion users. This provides you with the opportunity to gain more potential customers.
  2. Compliance and legislation - Americans with Disabilities Act (ADA) states that all electronic and information technology should be accessible to all, including those with disabilities. If you aren’t compliant, it could negatively impact your brand.
  3. Search Engine Optimisation ( SEO ) - Web accessibility and search engine optimization share a common goal. It is to help web users easily find and navigate through the content they need. Accessible applications will help you rank higher in the searches.
  4. Promotes Usability - Online content that meets accessibility requirements is likely to be more user-friendly for everyone. People without any physical disability, like those in rural areas and developing countries, could also benefit from it. It enhances the user experience.

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:

  1. Cover ARIA roles & attributes
  2. Color contrasts
  3. Font sizes

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 addons 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:

  1. Simple and easy to integrate - If you use Storybook to document and host your components in isolation, you must add @storybook/addon-a11y to the addon section in the storybook config file. That's all, and the setup is done. It's that easy to integrate. This will automatically check for common accessibility issues.
  2. Component-level violations - Unlike most auditing tools today that provide page-level violations, It helps pinpoint violations on a component level. This enables you to get feedback as you write your components.
  3. Great feedback - It pinpoints violations on a component level and provides resources and links to educate about the violations and how to fix them.
  4. Automation - The changes made to a component could introduce new accessibility issues. You'll want to test all your components before raising a pull request to catch such regressions. It does it by running the accessibility tests in your test automation pipeline with the help of Storybook test runner and axe-playwright.
  5. Flexibility to choose your rules - Storybook allows users to select their own rules and features from the Axe API in their Storybook configuration. There are options to include or exclude rules based on the accessibility standards you want to follow.
  6. Color blindness emulator - A11y provides a color blindness emulator for visual testing. This helps you relate to users with disabilities in ways that wouldn't have been possible before. It also reports the percentage of users that come to web applications with each disability. This helps you decide the critical ones to fix at the earliest.
Storybook A11y’s color blindness emulator reports the percentage of users that come to web applications with each disability

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.

Storybook A11y’s 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 primary or secondary button based on the type prop passed to it. Let’s write stories for both of them as shown below:


const ButtonTemplate = (props) => ...;

export const PrimaryButton = ButtonTemplate.bind({});

PrimaryButton.args = {
  type: 'primary',
};

SecondaryButton.args = {
  type: 'secondary',
};

Storybook A11y’s accessibility audit for a primary button component with no violations
Storyboook A11y’s accessibility audit for a secondary button component with a violation for insufficient color contrasts.

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.

Storybook test runner’s results on running accessibility tests for all the components

Enjoying this article? Don't miss out on more exclusive insights and real-life digital product stories at LeadReads. Read by Top C Execs.
Join
here.

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.

Storybook A11y’s accessibility audits displays rules within the incomplete tab that have met the criteria.

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.

Storybook A11y’s accessibility audits display rules within the passes tab that have met the criteria. It provides information on each rule and a link containing in-depth information. A list of flagged elements by the selector path is also displayed under the rule information. A severity tag is attached to each element to indicate the urgency of fixes to be made,
Storybook A11y’s highlight results checkbox is located to the right of each rule. Enabling it flags DOM elements in the Storybook canvas.

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:

  1. Building Empathy: Empathy is the foundation of accessibility culture, and your organization’s leadership can foster empathy with inclusive policies.
  2. Write and document all possible stories for a component: If you can run accessibility audits on every component and its variations, you can build and ship accessible components.
  3. Track and fix violations as you build: It’s important to track and fix all the accessibility violations before you commit them. This shortens the feedback loop and helps you ship accessible components faster.
  4. Set up accessibility tests in your CI: This is important to catch regressions and ensure all components at the time of merge passed the accessibility tests

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 defence 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.