要素を非活性にするのに、まさか disabled を使ってないよね？

# はじめに
フロントエンドエンジニアのみなさん、
要素を非活性にする際、`disabled=true`を使っていませんか？

**アクセシビリティ的にそのやり方は良くないです。**

最近、アクセシビリティに配慮したアプリケーションの開発に携わっています。
その中でシニアエンジニアから頂いたフィードバックについて共有したいと思います。


# 結論
`disabled=true` ではなく **`aria-disabled=true`** を使う

## disabledの場合
`disabled`が付与されている要素は**フォーカスができません**。

そのため、キーボードを用いて操作しているユーザーにとって、
要素の存在を認知しにくいものにしてしまいます。
（フォーカスできない要素は存在しない要素とほぼ同義だから）


![画面収録 2024-09-03 21.39.22.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2508607/0cd8e07b-e483-a797-d53c-f12bbc045562.gif)


ちなみにテキストフィールドを`disabled`にすると上記のように、ボタンのフォーカスがスキップされ、スクリーンリーダーでも検知することができません。
キーボード操作をしている方からすると、
「あれ？？ 入力エリアがない？？」　と思ってしまいます。

これが操作の途中、例えばバリデーションなどの仕様で`disabled`になってしまうと、ユーザーからすれば急に要素が消えるように感じてしまい、誤作動を起こす要因になります。

アクセシビリティを考慮するなら`disable`を使用しない方がベターです。

代わりに`aria-disabled` を使う方が良いです。

（※ `disable`と`aria-disabled` の兼用はできないので注意）

## area-disabledの場合

カーソルを当てることができるようになります。
![画面収録 2024-08-14 20.55.16.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2508607/36dc81f0-ca3f-3245-778e-30066b991835.gif)

また、スクリーンリーダーなどからは無効であることを認識できるようになります。

[aria-disabled](https://developer.mozilla.org/ja/docs/Web/Accessibility/ARIA/Attributes/aria-hidden)
>aria-disabled 属性は、 true に設定されると、その属性が設定されている要素や、フォーカス可能なすべての子孫要素が無効状態であることを意味していることを示します。この宣言は、スクリーンリーダーのような支援技術を使用する人々に、そのような要素は編集やその他の操作ができないことを意味していることを知らせます。


`Voice Over` では、無効なフィールドにカーソルが当たると「淡色表示」として読み上げられるようになります。

<img width='500px' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2508607/12913636-ea56-18f3-3a95-b88414a17679.png'>


**しかし、`disabled` と違って、要素の機能が変更されません!!**

つまり、 `input` フィールドに `aria-disabled` を指定しても
**見た目も変わらないし、入力できるし、クリックもできます。**

そのため、前述した機能が欲しい場合は、**手動での実装が必要です!**

## アクセシビリティに配慮したテキストフィールド

例えば以下のようなテキストフィールドを作成するとします。
（reactで書いてます）

<img width='400px' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2508607/00295c51-9b39-b4e6-603d-8534c337990b.png'>

追加で実装するのは以下です。
- css で背景とホバーのデザインを当てる
- 読み取りしかできないようにする

```text-field.tsx
import classNames from 'classnames';
import styles from './text-field.module.scss';

type TextFieldProps = {
  disabled?: boolean;
};

const style = {
  padding: '4px',
};

export const TextField = ({ disabled = false }: TextFieldProps) => {
  return (
    <div>
      <input
        style={{ ...style }}
        className={classNames(disabled && styles.disabled)}
        type="text"
        aria-disabled={disabled ? true : undefined}
        readOnly={disabled ? true : undefined}
      />
    </div>
  );
};
```
```text-field.module.scss
.disabled {
  background-color: #e9eaea;
  cursor: not-allowed;
}
```
`readOnly` + `CSS` と簡単に表現することができます。

`area-disabled=true` で得られる恩恵は、キーボード操作で要素間を移動する時に、ボタンの状態に拘らず同じキーダウン回数で同じ要素に辿り着けるため、ユーザが誤作動を起こしにくいことです。

今回は`text-field`を例に挙げましたが、これは `button`や`checkbox`などについても同様です。
`disabled`ではなく、`area-disabled`を使用します。 

# まとめ
ここまで見ていただき、ありがとうございます！

ちなみに、フィードバックしてくださったシニアエンジニア曰く、
「アクセシビリティはアメリカでは当たり前。 `aria-disabled` を使うのは普通だよ」

とのこと。
調べても`aria-disabled`と`disabled`のどっち論争が散見されますが、アクセシビリティに厳しいアメリカでは`aria-disabled`一択のようです。

こういったフィードバックを得られる環境がまじでありがたい😭。


# 参照
[aria-disabled](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-disabled)