トピックを検索
色だけで示された必須項目
予約フォームが必須項目のラベルを赤くしているだけで、言葉も記号もrequired属性もないため、色が見えてその意味を推測できる人にしか、どの欄が必須か分かりません。
問題
赤色が見えない人や、その意味を知らない人は、フォームが差し戻されて初めて、どの欄が必須だったかを知ります。
料理教室の予約フォームで、お名前、メールアドレス、電話番号、食事の制限を入力します。「お名前」と「メールアドレス」のラベルは赤く、「電話番号」と「食事の制限」は濃い灰色です。デザイナーは赤を「必須」の意味で使い、本人には明らかです。しかし赤と灰色を見分けられない人には、普通のラベルが四つ並んでいるだけです。スクリーンリーダーでは「お名前、編集テキスト」「電話番号、編集テキスト」と聞こえ、違いがありません。電話番号だけを入力して「予約する」を押すと、二つのエラーとともにフォームが戻り、そこで初めて決まりが分かります。
3.3.2は、入力が必要な場面でラベルや説明を求めています。どの欄を入力する必要があるかもその説明の一つで、W3Cの解説書も必須項目を例に挙げています。この例では、その説明が色だけで示され、色の意味もページのどこにも書かれていないため、多くの人に届きません。欄にはrequired属性もないので、ブラウザーは支援技術に必須だと伝えられません。色だけの印は1.4.1も満たしませんが、どちらの修正も同じで、説明を言葉にすることです。
赤の意味を知っている作り手には、この問題が見えません。それ以外の人は、送信の失敗という形で代償を払います。スマートフォンでは、エラーの欄を探してフォームを上までスクロールし直すことも多くなります。
10グループ中4グループに影響
- 全盲 (影響あり)
- 弱視 (影響あり)
- 色覚 (影響あり)
- ろう (影響なし)
- 難聴 (影響なし)
- 発話 (影響なし)
- 手の操作 (影響なし)
- 届く範囲・力 (影響なし)
- 認知 (影響あり)
- 光過敏 (影響なし)
- 色を知覚しない 赤と黒を見分けられない人には、同じラベルが四つ並んでいるだけで、二つの欄が必須だという印がありません。
- 視覚を使わない required属性がないため、スクリーンリーダーはどの欄も同じように読み上げ、色は何も伝えません。
- 言語・認知・学習の能力が限られる 赤色が見えても意味は推測するしかなく、間違いはフォームがエラーとともに戻ってきて初めて分かります。
- 視覚が限られる 大きく拡大すると一度に一つのラベルしか見えず、色を比べる相手のラベルがありません。
スキャナーは各欄にラベルがあるかを確認し、この例にはラベルがあるため合格します。赤いラベルが「必須」の意味であることや、サーバーが空のメールアドレスを拒否することは、どのルールにも分かりません。AIによる手早い修正は、赤い欄にaria-required="true"を足しがちです。スクリーンリーダーでは「必須」と聞こえるようになりますが、画面は変わらず、色を読み取れない人は推測したままです。説明のないアスタリスクを足すだけの修正もよくあり、星の意味は伝わりません。見える印とサーバーの要件が一致しているかは、人が見比べて確かめます。
試してみる
どの欄を入力する必要がありますか?考えてから、Tabキーでフォームを移動してください。
グレースケールをオンにすると、色のないフォームを確認できます。下の欄で、スクリーンリーダーが「必須」と読み上げるか確認してください。
問題あり 直してみませんか?
(Tabで入力欄へ移動)
再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。
修正方法
ラベルに言葉で書き、同じ欄にrequired属性を付けます。
- 1どの欄が必須かを、ラベル内か最初の欄より前の説明で、見えるテキストとして示す。
- 2必須の欄すべてに、そしてそれだけにrequired属性を付ける。
- 3色、太字、プレースホルダーだけを印にしない。
<style> .is-required { color: #b3261e; }</style> <label for="name" class="is-required">お名前</label><input id="name" name="name" type="text" autocomplete="name"> <label for="email" class="is-required">メールアドレス</label><input id="email" name="email" type="email" autocomplete="email"> <label for="phone">電話番号</label><input id="phone" name="phone" type="tel" autocomplete="tel"> <label for="diet">食事の制限</label><input id="diet" name="diet" type="text">必須と任意の違いは、ラベルの色だけです。その意味はページのどこにも書かれておらず、コード上でも必須の欄はありません。
言葉がラベルの一部なので、誰もが欄の名前と同じ場所で読め、凡例も要りません。required属性が支援技術にも同じことを伝え、スクリーンリーダーは「お名前(必須)、編集テキスト、必須」と読み上げます。言葉があれば、赤色を飾りとして残しても構いません。
三つとも3.3.2を満たし、どれもrequired属性を残します。ラベルに「(必須)」と書く方法は、説明もほかの要素も要らないので、必須の欄が半分ほどより少ないときに選びます。ほとんどの欄が必須なら、任意の欄に印を付けます。フォームが落ち着いて読め、言葉は対象の欄ごとに付いたままです。アスタリスクは最も短く見慣れた方法で、すでにすべてのフォームで使っているサイトに向いています。サイト全体で統一し、星は見える大きさと濃さにします。
説明の一文は目に入る場所に。 任意の欄に印を付ける方法とアスタリスクは、どちらも最初の欄より前の一文に頼ります。ページの冒頭やフッターではなくフォームのすぐ上に置き、拡大表示の人やリンクからフォームに来た人も必ず通るようにします。
言葉はラベルの中に。 「(必須)」や「(任意)」は、プレースホルダーやツールチップ、別のdivではなくlabel要素の中に書きます。欄の隣に見え、音声操作やスクリーンリーダーが使う名前にも含まれます。
サーバーが必要とする欄だけに。 空だと拒否される欄にだけrequiredを付けます。「必須」と書いてあるのに空でも通る欄や、その逆があると、利用者は印を信用しなくなります。フォームのコンポーネントで、印と属性を同じ設定から生成し、ずれないようにします。
ブラウザーの検証。 required属性は、ブラウザー自身の検証とメッセージの吹き出しも有効にします。独自のエラーメッセージを出す場合は、formにnovalidateを付けます。欄にはrequiredが残るので、スクリーンリーダーは引き続き必須と読み上げます。メッセージそのものはフォームのエラーのガイドを参照してください。
独自のコントロール。 divで作ったドロップダウンや日付選択にはrequiredを付けられません。見える言葉と合わせてaria-required="true"を付けるか、できればネイティブの部品に置き換えます。
ラジオボタンとチェックボックスのグループ。 言葉は各選択肢ではなくlegendに書きます(「受講日(必須)」)。requiredはグループ内の各ラジオボタンに付けます。
「必須」バッジ。 日本のフォームでよく使われる「必須」のバッジはテキストなので基準を満たします。ラベルの中に置き、十分なコントラストを確保し、色だけに頼らないようにします。
修正の確認
マウスを使わない4つの確認
確認方法: キーボード、スクリーンリーダー、ズーム
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。フォームに欄を追加したときや、共通の入力欄コンポーネントを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。入力前にどの欄が必須かを知る方法を扱い、送信後のエラーメッセージは扱いません。日付の順序や郵便番号の形式のような書式も説明の一つで、それぞれにテキストが必要です。外部ウィジェットやコンテンツ編集者が作ったフォームも同じように確認してください。実際に使用する支援技術で、操作全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。