アクセシブルでdisabledなButtonコンポーネントを作成
button
要素を非活性にする場合にdisabled
属性がよく利用されます。
ただしdisabled
属性には問題があってボタンにフォーカスが当たらなくなります。
フォーカスが当たらないと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でどのように読み上げられるか見ていきましょう。
淡色表示として非活性であることが伝えれます。
このように一工夫することでWebサイトのアクセシビリティは向上させることができます。
Discussion