🔘

アクセシブルでdisabledなButtonコンポーネントを作成

2024/04/11に公開

button要素を非活性にする場合にdisabled属性がよく利用されます。

ただしdisabled属性には問題があってボタンにフォーカスが当たらなくなります。

https://azukiazusa.dev/blog/use-aria-disabled-to-give-focus-to-disabled-button/

フォーカスが当たらないとUI要素として認識がされにくいですのでフォーカスを当てた上で非活性であることを明示しようというのが本記事の意図です。

aria-disabledを利用する

基本的な対応は参照した記事に書かれている通りaria-disabled属性を利用するです。

ただ、以下のように普通に利用するだけではクリックイベントが実行されてしまいます。

<button aria-disabled onClick={() => console.log('click')}>
  ボタン
</button>

これを回避するためにButtonコンポーネントを作成してaria-disabled属性を受け入れる準備をしていきましょう。

クリックイベントが発生しないように作成

クリックイベントが発生しないようにと考えるとCSSのpointer-events: noneを思い浮かべる人もいるかも知れませんが、pointer-events: noneで制御できるのはマウス操作のみです。キーボード操作でエンター等を押されるとクリックイベントが発生してしまいます。

そのためJSによる制御が必要です。

以下のButtonコンポーネントではaria-disabled時にe.preventDefault();が実行されるようにすることでイベントの実行を抑制しています。

type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>;

const Button = ({ onClick, ...props }: ButtonProps) => {
  // aria-disabled時にクリックイベントが発火しないようにするイベント
  const disabledClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
    e.preventDefault();
  };

  return <button onClick={props['aria-disabled'] ? disabledClick : onClick} {...props} />;
};

disabled属性でも制御可能に

先程作成したButtonコンポーネントには一点懸念点があります。

非活性の制御にaria-disabled属性という特殊な属性を使っていることです。

多くのUIコンポーネントではdisabled属性で制御するのが一般的な中、aria-disabled属性を利用するというのは正しく運用されない可能性があります。

そのためaria-disabled属性だけではなくてdisabled属性でも同様の処理になるように修正を加えます。

以下ではButtonコンポーネントがdisabled属性を受け取った場合にaria-disabled属性に変換してbutton要素に受け渡しています。

type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>;

const Button = ({
+disabled,
 onClick,
 ...props
}: ButtonProps) => {
  // aria-disabled時にイベントが発火しないようにするイベント
  const disabledClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
    e.preventDefault();
  };

  return (
    <button
+     aria-disabled={disabled}
-     onClick={props['aria-disabled'] ? disabledClick : onClick}
+     onClick={disabled || props['aria-disabled'] ? disabledClick : onClick}
      {...props}
    />
  );
};

スタイルの調整

aria-disabledの場合はdisabled属性を指定した場合と違いスタイルはそのままです。
CSSで非活性であることがわかるようにデザインを調整しましょう。

属性セレクタを利用すればaria-disabled時の指定が可能です。

[aria-disabled] {
  color: rgba(16, 16, 16, 0.3);
  background-color: rgba(239, 239, 239, 0.3);
  border: 1px solid rgba(118, 118, 118, 0.3);
}

これで アクセシブルなButtonコンポーネントは完成です。

スクリーンリーダー(Mac VoiceOver)での読み上げ

最後にスクリーンリーダーのMac VoiceOverでどのように読み上げられるか見ていきましょう。

ブラウザ上のボタン要素にフォーカスが合って、「ボタン、淡色表示、ボタン」と読み上げるVoiceOverのテキストが表示されている画像

淡色表示として非活性であることが伝えれます。

このように一工夫することでWebサイトのアクセシビリティは向上させることができます。

株式会社トゥーアール

Discussion