フォームはユーザーとサービスとを結ぶ重要な要素です。入力欄やエラーメッセージが適切に設計されていないと、ユーザーは入力に失敗したり、途中で離脱してしまうかもしれません。
今回は、フォームを誰でも安心して使えるようにするアクセシビリティの工夫を紹介します。

ラベルと入力欄の関連付け

フォームでは、入力欄とラベルを正しく関連付けることが重要です。見た目では隣接していても、スクリーンリーダーはラベルと入力欄を結びつけていません。

関連するWCAG達成基準

WCAG 2.1 – 1.3.1 情報及び関係性
WCAG 2.1 – 3.3.2 ラベル又は説明

未対応時のユーザーへの影響

どこに入力するか分からなくなる

関連付けがない場合スクリーンリーダーに「入力欄」とだけ伝えられ、ユーザーは「ここには何を入力すればよいか」が分からなくなります。

実装方法

以下のいずれかの方法で実装していきます。

1.forとidを使って関連付ける

<label for="email">メールアドレス</label>
<input id="email" type="email" name="email">

2.ラベルで囲む

<label>
  メールアドレス
  <input type="email" name="email">
</label>

3.aria-labelledbyを使用する

複雑なフォームでは、forとid の関連付けでは足りないケースがあります。
その場合は、aria-labelledbyを使って複数の要素をラベルとして指定できます。

<p id="zip">郵便番号</p>
<input type="text" id="zip-part1" size="3" aria-labelledby="zip">
<span>-</span>
<input type="text" id="zip-part2" size="4" aria-labelledby="zip">

4.aria-labelを使用する

デザイン上の理由でラベルを表示しない場合、スクリーンリーダー用にaria-labelを使用します。
ただし、可能な限り視覚的にラベルを表示することが望ましいため、aria-labelは最終手段として使いましょう。

<input type="email" name="email" aria-label="メールアドレス">

エラーを伝える

入力時に誤りがあった場合、確実にエラーをユーザーに通知する仕組みが必要です。

関連するWCAG達成基準

WCAG 2.1 – 3.3.1 エラーの特定
WCAG 2.1 – 3.3.3 エラー修正の提案

未対応時のユーザーへの影響

エラーに気づけない

エラーメッセージを視覚的に赤字で表示するだけでは、視覚に頼れないユーザーには伝わりません。

離脱につながる

エラーに気づかなければフォームを送信できず、利用を断念してしまう可能性があります。

実装方法

エラーメッセージを入力欄と関連付ける

aria-describedby属性とidを使うことで、スクリーンリーダーがエラーメッセージを読み上げます。

<label for="email">メールアドレス</label>
<input id="email" type="email" aria-describedby="error-email">
<p id="error-email" class="error">メールアドレスを入力してください</p>

即座に通知する

エラーが発生したら、role="alert"で即時通知できます。
入力中に頻繁に通知すると混乱を招くため、送信時や入力欄からフォーカスを外したタイミングで通知するのが望ましいです。

<label for="password">パスワード</label>
<input id="password" type="password" aria-describedby="error-pass">
<p id="error-pass" role="alert">パスワードは8文字以上で入力してください</p>

具体的に示す

エラーメッセージは「エラーがあります」だけでは不十分です。
何が違っているか、何を修正すべきかを具体的に伝えましょう。

必須項目を明示する

フォームには必須項目と任意項目があり、どこまで入力すればよいのかを正確に伝えることが大切です。

関連するWCAG達成基準

WCAG 2.1 – 3.3.2 ラベル又は説明

未対応時のユーザーへの影響

入力に一手間かかる

どの入力欄が必須なのかが分からないと入力し直す手間が発生し、ユーザーの不満につながります。

色や記号だけでは伝わらない

「赤字は必須」や「*印は必須」だけではユーザーによっては伝わらない事があります。

実装方法

aria-required=”true”を使用する

入力必須のフォームには視覚的に「必須」と文字で表示した上で、aria-required="true"を付与し、スクリーンリーダーにも必須項目であることを伝えます。
aria-required=”true”: 必須項目であることを伝える

色や記号に頼らない

色や記号に頼らず「必須」「任意」と文字で表示しましょう。

グループ化する

姓と名が分かれたフォームなど複数の入力欄が関連している場合、構造的にグループ化することでユーザーに意図が伝わりやすくなります。
また、スクリーンリーダーに対しても「ここから関連する入力項目です」と明示することができます。

関連するWCAG達成基準

WCAG 2.1 – 1.3.1 情報及び関係性

未対応時のユーザーへの影響

フォームの区切りが分からなくなる

スクリーンリーダー利用者は「ここから氏名入力」「ここから住所」といったまとまりを把握できず、ただの連続した入力欄として認識してしまいます。

実装方法

fieldsetとlegend を使う

<fieldset>
  <legend>氏名</legend>

  <label for="last-name">姓</label>
  <input id="last-name" type="text" name="last-name">

  <label for="first-name">名</label>
  <input id="first-name" type="text" name="first-name">
</fieldset>

role=”group”を使う

技術的な制約でfieldset が使えない場合はrole="groupを代替手段として利用します。
role=”group”: 複数のフォーム要素がひとまとまりであることを伝える

<div role="group" aria-label="住所">
  <label for="zip">郵便番号</label>
  <input id="zip" type="text">

  <label for="address">住所</label>
  <input id="address" type="text">
</div>

グループとエラーを紐付ける

<fieldset aria-describedby="name-error">
  <legend>氏名</legend>

  <label for="last-name">姓</label>
  <input id="last-name" type="text" name="last-name">

  <label for="first-name">名</label>
  <input id="first-name" type="text" name="first-name">
</fieldset>
<p id="name-error" role="alert">全角で入力してください</p>

送信後にフィードバックを伝える

フォームの送信後はフィードバックを確実に伝えましょう。

未対応時のユーザーへの影響

結果が分からず不安になる

フィードバックがなければ、ユーザーは操作が成功したかどうか判断できません。
「送信が成功したか」「エラーがあったのか」が伝わらないと、再送信や離脱の原因になります。

実装方法

フィードバックを適切に伝える

送信後の状態(成功・失敗)をユーザーに確実に伝えます。aria-liveroleを使うと、スクリーンリーダーに即時通知できます。

<!-- 成功メッセージ -->
<p role="status">送信が完了しました。</p>

<!-- エラーメッセージ -->
<p role="alert">送信に失敗しました。</p>

status: 重要ではあるものの緊急ではない状態変化の通知
alert: ユーザーの即時的な注意を必要とする重要な通知

処理中の明示をする

送信中は「処理中」であることをユーザーに伝える必要があります。

<form aria-busy="true">
  <!-- 入力フォームやボタン -->
</form>

aria-busy=”true”: その要素が処理中であることを伝えます。

まとめ

フォームのアクセシビリティは、ユーザー体験の質を大きく左右します。小さな改善でも入力体験はぐっとよくなります。
実装するときは、ぜひ今回のポイントを参考にしてみてください。