无障碍性

测试组件是否符合 Web 无障碍性标准

在 Github 上查看

storybook-addon-a11y

此 Storybook 插件可以帮助您使 UI 组件更易于访问。

框架支持

Screenshot

入门

首先,安装插件。

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

将此行添加到您的 main.js 文件中(如果需要,在您的 Storybook 配置目录中创建此文件)。

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

这是一个用于测试插件的示例故事文件

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>
);

处理失败规则

当 Axe 在故事中报告无障碍性违规时,您可以根据需要通过多种方式处理这些失败。

故事级别覆盖

在故事级别,使用 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,
        },
      ],
    },
  },
};

或者,您可以在故事中禁用特定规则

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

提示:在注释中清楚地解释为什么覆盖了某个规则,这将有助于您和您的团队追溯为什么某些违规行为未被报告或需要解决。例如

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,
        },
      ],
    },
  },
};

全局覆盖

当您想忽略无障碍性规则或更改其在所有故事中的设置时,请在 Storybook 的 preview.ts 文件中设置 parameters.a11y.config.rules。这对于忽略 Axe 常规报告的误报特别有用。

// .storybook/preview.ts

export const parameters = {
  a11y: {
    config: {
      rules: [
        {
          // This tells Axe to run the 'autocomplete-valid' rule on selectors
          // that match '*:not([autocomplete="nope"])' (all elements except [autocomplete="nope"]).
          // This is the safest way of ignoring a violation across all stories,
          // as Axe will only ignore very specific elements and keep reporting
          // violations on other elements of this rule.
          id: 'autocomplete-valid',
          selector: '*:not([autocomplete="nope"])',
        },
        {
          // To disable a rule across all stories, set `enabled` to `false`.
          // Use with caution: all violations of this rule will be ignored!
          id: 'autocomplete-valid',
          enabled: false,
        },
      ],
    },
  },
};

禁用检查

如果您希望完全禁用某些故事的 a11y 检查,则可以使用故事参数来控制。

export const MyNonCheckedStory = () => <SomeComponent />;
MyNonCheckedStory.parameters = {
  // Avoid doing this, as it fully disables all accessibility checks for this story,
  // and consider the techniques described above.
  a11y: { disable: true },
};

参数

为了获得更多自定义功能,请使用参数配置 aXe 选项。您也可以在 故事级别 覆盖这些选项。

import React from 'react';
import { addDecorator, addParameters, storiesOf } from '@storybook/react';

export default {
  title: 'button',
  parameters: {
    a11y: {
      // optional selector which element to inspect
      element: '#storybook-root',
      // axe-core configurationOptions (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#parameters-1)
      config: {},
      // 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 const accessible = () => <button>Accessible button</button>;

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

使用测试运行器自动执行无障碍性测试

默认情况下,测试运行器不会应用您在故事中设置的任何规则。您可以通过 遵循 Storybook 文档中的指南 配置运行器以正确应用规则。

路线图

  • 使 UI 可访问
  • 在故事中显示违规位置。
  • 添加更多示例测试
  • 添加测试
  • 使 CI 集成成为可能
作者
  • kasperpeulen
    kasperpeulen
  • jreinhold
    jreinhold
适用框架
    Angular
    Ember
    HTML
    Marko
    Mithril
    Preact
    Rax
    React
    Riot
    Svelte
    Vue
    Web Components
标签