フォームのアクセシビリティについてまとめてみる

フォーム実装時に注意したいアクセシビリティのポイントを、ラベル・エラー通知・placeholderやdisabledの扱いなどを中心に、WCAGの達成基準とあわせて備忘録としてまとめました。

はじめに

フォームはユーザーが入力するための要素であるため、フォームのアクセシビリティを考える必要があります。
また、サイトによってはフォームに問い合わせてもらう、資料請求まで行うことが目的である場合あるため、フォームのアクセシビリティを考えることは重要だと思っています。
全てを網羅してまとめられているわけではありませんが、実装経験や調査を通してわかったことを中心に備忘録としてまとめていこうと思います。

デモサイト

作成したデモサイトはこちらになります。

フォームのアクセシビリティ デモサイト

フォーム実装の時に注意すること

最初に実装時に注意してみておくことを挙げてみます。

  • 入力項目にラベルをつける
  • 色だけで必須やエラーを表現しない
  • 必須の文字が認識できない位置にない
  • 入力補完を利用できるものはautocompleteを使う
  • 入力要素がフォーカスを受け取れるようにする
  • エラーが出たときに支援技術に通知され、適切に読み上げられる
  • disabledの使用は避ける
  • placeholderを使わない

補足

要件によって、エラーの通知タイミングや通知方法を考える必要があるので、この限りではないでしょう。

入力項目にラベルをつける

htmlのセマンティクスを意識して、label要素を使います。
labelfor属性と入力要素のidも忘れずに設定しましょう。
スクリーンリーダーで使用時、入力要素にフォーカスが当たるとidで紐づけたlabelの内容と一緒に読み上げてくれるので、どの要素を入力しているかがわかるようになります。

<!-- 例 -->
<label for="name">名前</label>
<input type="text" id="name" name="name" />
<label>: ラベル要素 | MDN

色だけで必須やエラーを表現しない

色だけで必須やエラーを表現せず、テキストとして情報を伝えるようにします。
テキストでないと、ロービジョンの方は判別できなかったり、スクリーンリーダーユーザが認識できなかったりします。
一般のユーザーにとっても、「赤=必須」を覚えていなければならず、負担になってしまいます。

<!-- 悪い例 -->
<p>赤の要素は必須です。</p>
<label for="name" style="color: red">名前</label>
<input type="text" id="name" name="name" required />
<!-- 良い例 -->
<label for="name">名前<span>必須</span></label>
<input type="text" id="name" name="name" required />

該当するWCAG

達成基準 1.4.1:色の使用 (レベル A) 達成基準 4.1.2:名前 (name)・役割 (role)・値 (value)

必須の文字が認識できない位置にない

必須の文字が、ラベルとあまりにも離れすぎていると、視野狭窄の方が気付けない可能性があります。 ラベルと必須のテキストが離れすぎていたり、両端に配置しするようなレイアウトは避ける方が良いでしょう。

<!-- 悪い例 -->
<label for="name" style="display: flex; justify-content: space-between;">
<span>名前</span>
<span>必須</span>
</label>
<input type="text" id="name" name="name" required />

該当するWCAG

調べてみたところ、直接該当しそうな項目はありませんでした。 デザインとの兼ね合いにもなってくるので、現実的に難しそうだなと思いつつ、今回挙げています。 配慮できそうならするくらいの感覚でもいいのかもしれません。

情報源はデジタル庁のブログ記事になります。

デジタル庁 アクセシビリティに関する記事

入力補完を利用できるものはautocompleteを使う

入力時に「名前」や「住所」「電話番号」といった要素は、他のフォームでも使いまわしているケースが多いです。 また、場合によっては何を入力するべきか瞬時に把握できないこともあります。 autocomplete属性を使うことで、入力補完を利用できるので負担が減ります。また、ユーザーが何を入力するべきか理解する手助けにもなります。 また、autocomplete="off"は入力補完を切ることになるので、毎回入力が異なる補完の効かない項目でのみ使用するようにしましょう。

<div>
<label for="name">名前<span>必須</span></label>
</div>
<input type="text" id="name" name="name" required />

該当するWCAG

達成基準 1.3.5:入力目的の特定 (レベル AA)

入力要素がフォーカスを受け取れるようにする

入力要素がフォーカスが受け取れる・受け取ったことがわかるようにします。 outline: none;はフォーカスインジケータが表示されなくなってしまうので、見直すか代替手段を用意しましょう。

該当するWCAG

達成基準 2.4.7:フォーカスの可視化 (レベル AA)

エラーが出たときに支援技術に通知され、適切に読み上げられる

今回はライブリージョンを使ってみます。

<label for="name">名前<span>必須</span></label>
<input
type="text"
id="name"
aria-describedby="name-error"
aria-invalid="true"
autocomplete="name"
required
name="name"
/>
<!-- ↓以下はバリデーションチェック後に出す -->
<div
class="error"
role="alert"
aria-atomic="true"
aria-live="assertive"
id="name-error"
>
<span>名前を入力してください</span>
</div>

入力要素 aria-describedbyは入力要素にフォーカスが当たった時に、指定した要素を読み上げてくれます。 aria-invalidは入力値が無効であるかどうかを通知します。

エラー本体 class="error"の要素はバリデーションチェック後にエラーがあれば出すようにしてください。
role="alert"aria-live="assertive"aria-atomic="true"の複合です。
aria-live="assertive"はユーザーへの通知を即座に行います。

今回のエラー通知にはライブリージョンを使っていますが、必ずしもライブリージョンを使うのが正解ではないと思っています。 代替手段としてはfocusを当てることでエラー文を読み上げるようにすることも手段として考えられます。 実際にライブリージョンを使うか、別の手段を使うかはフォームのフローや構成によっても変わってきそうなので、柔軟に考えて行けたらいいなと思います。

該当するWCAG

達成基準 3.3.1:エラーの特定 (レベル A) 達成基準 3.3.3:エラー修正の提案 (レベル AA)

disabled属性の使用を避ける

今まで入力エラーや必須項目の入力時には、送信ボタンがdisabled属性を使うのが良いと持っていたのですが、フィードバックや調査しているうちにあまりよくないと言うことがわかってきました。
理由としては、キーボード操作でフォーカスを受け取ることができないためです。また、視認性が悪くロービジョンユーザーが認識できない可能性があることや、「なぜ押せないのか、どうしたら押せるようになるのか」がユーザーにわかりにくいといった問題もあります。
スクリーンリーダーで無効であることは読み上げられるため、適切な場所でdisabledを使うようにしましょう。

無効ボタン(disabled)はタブフォーカスでアクセスできない | デジタル庁デザインシステム

該当するWCAG

実際には該当する項目が見当たりませんでした。 達成基準 1.4.3:コントラスト (最低限) (レベル AA) でみれば、ユーザーが操作できないユーザーインターフェースコンポーネントは、コントラスト要件を満たす必要はないとの記載があり、一見問題ないようにも思います。 一方で、一部の記事や書籍には、フォームの送信ボタンにdisabledを使用するのが適切ではないとされているものが多いです。
disabledの仕様上、フォーカスができないようになっているので、無効になっていることがわからないことが主な原因となります。
そのようなケースがあるかはわかりませんが、万が一フォームの送信ボタンにdisabledを使用する場合は、別のテキストとして、必須項目の入力やエラーの解決をしない限り、ボタンが押せるようにならない旨をおく必要がありそうです。

placeholderを使わない

<label for="name">名前<span>必須</span></label>
<input
type="text"
id="name"
autocomplete="name"
name="name"
placeholder="名前を入力してください"
/>

placeholderを使うと、入力欄にそのテキストが出てきます。一見問題ないように見えますが、スクリーンリーダーで読み上げられません。 また、コントラストも良くないことから、説明文はplaceholderを使わず、別のテキストとしておくことが望ましいです。
別テキストとしておく時には、aria-describedbyを使うと入力要素にフォーカスが当たった時に、説明文も一緒に読み上げてくれます。

<label for="name">名前<span>必須</span></label>
<input
type="text"
id="name"
autocomplete="name"
name="name"
aria-describedby="name-desc"
/>
<p id="name-desc">名前を入力してください</p>

該当するWCAG

達成基準 1.4.3:コントラスト (最低限) (レベル AA) 達成基準 3.3.2:ラベル又は説明 (レベル A)

最後に

今回はフォームのアクセシビリティについて、一度自分で整理してまとめてみました。
注意すべき点はここに記した限りではないと思いますが、基本的な方針はまとめられたと思います。

例えば、リアルタイムでエラーを出す時とエラーサマリーを出す時とでは、エラーの通知タイミングや方法が異なるかもしれません。 実際の要件ごとに注意して、実装して行けたらいいなと思います。
今回はここまでとなります。ありがとうございました!

参考

一覧に戻る