Skip to content

Latest commit

 

History

History
 
 

a11y

storybook-addon-a11y

This Storybook addon can be helpful to make your UI components more accessible.

Framework Support

Screenshot

Getting started

First, install the addon.

$ yarn add @storybook/addon-a11y --dev

Add this line to your main.js file (create this file inside your Storybook config directory if needed).

export default {
  addons: ['@storybook/addon-a11y'],
};

And here's a sample story file to test the addon:

import React from 'react';

export default {
  title: 'button',
};

export const Accessible = () => <button>Accessible button</button>;

export const Inaccessible = () => (
  <button style={{ backgroundColor: 'red', color: 'darkRed' }}>Inaccessible button</button>
);

Handling failing rules

When Axe reports accessibility violations in stories, there are multiple ways to handle these failures depending on your needs.

Story-level overrides

At the Story level, override rules using parameters.a11y.config.rules.

export const InputWithoutAutofill = () => <input type="text" autocomplete="nope" />;

InputWithoutAutofill.parameters = {
  a11y: {
    // Avoid doing this, as it will fully disable all accessibility checks for this story.
    disable: true,

    // Instead, override rules 👇
    // axe-core configurationOptions (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#parameters-1)
    config: {
      rules: [
        {
          // You can exclude some elements from failing a specific rule:
          id: 'autocomplete-valid',
          selector: '*:not([autocomplete="nope"])',
        },
        {
          // You can also signify that a violation will need to be fixed in the future
          // by overriding the result of a rule to return "Needs Review"
          // rather than "Violation" if the rule fails:
          id: 'landmark-complementary-is-top-level',
          reviewOnFail: true,
        },
      ],
    },
  },
};

Alternatively, you can disable specific rules in a Story:

export const Inaccessible = () => (
  <button style={{ backgroundColor: 'red', color: 'darkRed' }}>Inaccessible button</button>
);
Inaccessible.parameters = {
  a11y: {
    config: {
      rules: [{ id: 'color-contrast', enabled: false }],
    },
  },
};

Tip: clearly explain in a comment why a rule was overridden, it’ll help you and your team trace back why certain violations aren’t being reported or need to be addressed. For example:

MyStory.parameters = {
  a11y: {
    config: {
      rules: [
        {
          // Allow `autocomplete="nope"` on form elements,
          // a workaround to disable autofill in Chrome.
          // @link https://bugs.chromium.org/p/chromium/issues/detail?id=468153
          id: 'autocomplete-valid',
          selector: '*:not([autocomplete="nope"])',
        },
        {
          // @fixme Color contrast of subdued text fails, as raised in issue #123.
          id: 'color-contrast',
          reviewOnFail: true,
        },
      ],
    },
  },