Accessibility Testing
Catch accessibility issues early in your development workflow with Chromatic’s automated accessibility testing. Built on top of Storybook’s powerful accessibility testing capabilities, Chromatic helps teams ensure their components are inclusive and meet WCAG standards at scale.
Accessibility testing in Chromatic leverages Storybook’s a11y addon and axe-core to automatically detect up to 57% of WCAG issues. By integrating these tests into your Chromatic workflow, you can:
- Shift-left by catching accessibility violations early in the development cycle
- Ensure consistent accessibility standards across your application
- Track accessibility compliance over time
- Generate reports for accessibility audits
Getting Started
- Set up Storybook’s a11y addon:
npx storybook add @storybook/addon-a11y
- Start Storybook
npm run storybook
- Ensure that the Accessibility checkbox is ticked in the Testing Module
- Run tests
How It Works
During local development, accessibility errors will be reported in the Storybook sidebar. When you push changes to your repository, Chromatic will:
- Build your Storybook
- Run accessibility tests for each story
- Compare results against previous builds
- Generate detailed reports of any violations
Customize the accessibility testing rules
Customize your accessibility testing rules using the accessibility
parameter in your Storybook configuration. You can set these parameters at the story, component (meta), and project (global) levels. Learn more ».
For detailed configuration options, refer to the Storybook Accessibility tests documentation.
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
a11y: {
// Optional selector to inspect
element: '#storybook-root',
// axe-core configurationOptions (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#parameters-1)
config: {
rules: [
{
// The autocomplete rule will only run based on the CSS selector provided
id: 'autocomplete-valid',
selector: '*:not([autocomplete="nope"])',
},
{
// Setting the enabled option to false will disable checks for this particular rule on all stories.
id: 'image-alt',
enabled: false,
},
],
},
// axe-core optionsParameter (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#options-parameter)
options: {},
// Optional flag to prevent the automatic check
manual: true,
},
},
};
export default preview;
Frequently asked questions
How does this differ from Storybook's built-in accessibility testing?
Chromatic builds upon Storybook’s accessibility testing by providing automated testing at scale, historical tracking, and integrated reporting within your workflow.
Does this replace manual accessibility testing?
No, automated testing catches a subset of accessibility issues. Manual testing is still recommended for comprehensive accessibility compliance.
Why don't the accessibility results show violations, even though I know there are some?
Modern React components often use asynchronous techniques like Suspense or React Server Components (RSC) to handle complex data fetching and rendering. These components don’t immediately render their final UI state. Storybook doesn’t inherently know when an async component has fully rendered. As a result, the a11y checks sometimes run too early, before the component finishes rendering, leading to false negatives (no reported violations even if they exist).
This only impacts users using:
- Storybook 8.5+
- Async components (RSC, or using Suspense or similar)
- Stories without a play function that awaits for the final component state
To address this issue, enable the developmentModeForBuild
feature flag. This sets process.env.NODE_ENV
to development
when building your Storybooks. This ensures that React’s act
utility is used, which helps ensure that all updates related to a test are processed and applied before making assertions.
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
framework: '@storybook/your-framework',
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
features: {
developmentModeForBuild: true,
},
};
export default config;