forms について
forms は、フォーム、入力欄、検証フローを実装・レビューする人向けのアクセシビリティスキルです。ラベル、エラー対応、認証、送信時のフィードバックを扱い、適切な場面ではネイティブ HTML 要素を推奨します。
主な機能
- 01コントロールのラベルとエラー関連付け
- 02エラー概要とフォーカス移動
- 03入力タイプとオートコンプリート
- 04認証と貼り付けへの対応
- 05送信と非同期ステータスの通知
活用シーン
- 01フォームのラベルと検証メッセージを確認
- 02ログインや確認コード入力を改善
- 03送信後の通知とエラー回復を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mgifford/ accessibility-skills --skill formsインストール後、Claude Code で/formsを入力して読み込まれたか確認します。
同梱ファイルSYNC.md
詳細
フォームのアクセシビリティスキル
正規のソース:
mgifford/ACCESSIBILITY.mdのexamples/FORMS_ACCESSIBILITY_BEST_PRACTICES.mdこのスキルはそのファイルを基にしています。判断に迷う場合は、例を正としてください。
フォーム、入力、または検証フローを実装またはレビューする際は、これらのルールを適用してください。 プロジェクトにフォームが含まれる場合にのみ、このスキルを読み込んでください。
基本方針
フォームは、キーボード、タッチ、音声入力、スクリーンリーダー、画面拡大、ブラウザーの自動入力、パスワードマネージャー、その他の支援技術を使って、理解し、操作できる必要があります。要件は、最初の入力、検証、復旧、確認、送信、認証に適用されます。時間制限が不可欠でない場合、ユーザーは時間制限のあるフォームを完了できる必要があります。また、コンテンツや機能を失わずに、200%/400%のズームでフォームを完了できる必要があります。
ネイティブ HTML コントロールを優先してください。ネイティブコントロールでは文書化された要件を満たせない場合にのみ、カスタムウィジェットを作成してください。また、該当するキーボード、フォーカス、名前、ロール、状態、値の動作を実装してください。
重大度の尺度(このスキル)
| レベル | 意味 |
|---|---|
| 重大 | 1 つ以上の障害のあるユーザーグループにとって、タスクの完了を完全に妨げます |
| 深刻 | アクセスを大幅に妨げます。回避策を期待するのは妥当ではありません |
| 中程度 | 不便が生じます。過度な負担のない回避策があります |
| 軽微 | ベストプラクティスに達していません。アクセスへの影響はわずかです |
違反したルールだけで重大度を決めないでください。実際のフォームとタスクに基づいて判断してください。次の点を考慮します。問題によって送信や復旧が妨げられるか、認証、支払い、健康、法律、安全、または不可欠な公共サービスに影響するか、影響を受けるユーザー/コントロールの数、妥当な回避策があるか、共通コンポーネントに起因するか、データが失われる可能性があるか。
重大:ラベル
すべてのフォームコントロールには、プログラムで関連付けられたラベルが必要です。 ラベルの欠落は重大です — スクリーンリーダーのユーザーはフィールドを識別できません。
- プレースホルダーテキストだけをラベルとして使用しないでください。入力時に消え、コントラスト要件を満たさず、すべてのスクリーンリーダーで確実に読み上げられるわけではありません
- 必須フィールドは色だけでなく、テキストで示す必要があります
- 独自の
<label>の内側に配置されたコントロールも有効です - 表示される HTML ラベルが実用的でない場合に限り、
aria-label/aria-labelledbyを使用し、アクセシブルネームにユーザーに見える語句が含まれるようにしてください(音声入力を使うユーザーは、表示ラベルでコントロールを指定します) - コンテンツ自体がすでに名前を示しているコントロール(例:
<button>Save</button>)には、別のラベルは不要です
<input type="email" placeholder="Email address">
<label for="email">
Email address <span class="visually-hidden">(required)</span>
</label>
<input type="email" id="email" autocomplete="email" required>
aria-required について: HTML の required 属性がすでに指定されているネイティブ入力に、aria-required="true" を追加しないでください。重複し、アクセシビリティツリーに不要な情報が加わります。ネイティブ属性を使用できないカスタムウィジェット(例:role="combobox"、role="listbox")にのみ aria-required を使用してください。
必須/任意フィールド: 最初のフィールドより前に、必須フィールドをどのように識別するか説明してください(例:「『必須』と表示されたフィールドには入力が必要です」)。アスタリスクや色だけに頼らないでください。少数の必須フィールドに印を付けるほうが明確な場合は、すべての任意フィールドに印を付けないでください。その逆の場合も同様です。
重大:エラーの識別
エラーはプログラムで該当するフィールドに関連付ける必要があります。 エラーを識別できない状態は重大です。エラーが発生していることを、視覚障害のあるユーザーが認識できなくなります。
- バリデーションでフィールドが無効と判定された後に
aria-invalid="true"を設定し、修正後は無効状態とエラーとの関連付けを解除します - エラーメッセージは具体的で、対処方法がわかる内容にします。「入力が無効です」だけでは不十分です
- エラーを示すために色やアイコンだけを使用しないでください
aria-describedby(またはテスト済みのaria-errormessageの実装)を使ってエラーメッセージをフィールドに関連付けます。既存のヒントとの関連付けも維持してください- セキュリティ上必要な場合を除き、入力済みの値を保持します
<label for="email">Email address</label>
<p id="email-hint">We will send the receipt to this address.</p>
<input id="email" name="email" type="email" autocomplete="email"
aria-invalid="true" aria-describedby="email-hint email-error">
<p id="email-error">
<strong>Error:</strong> Enter an email address in the format [email protected].
</p>
ページ読み込み時点ですでに表示されているエラーテキストに role="alert" を設定しないでください。ライブリージョンが通知するのは、ライブリージョンの設定後に行われた変更だけです。支援技術でテストせずに、複数の通知方法を競合する形で組み合わせないでください。
重大:エラーの概要
複数のフィールドでエラーが発生する可能性がある場合、フォームが長い場合、エラーがビューポートの外にある場合、またはユーザーがエラー箇所を見つけにくい場合は、エラーの概要を表示してください。複数のエラーがあるフォーム、長いフォーム、複雑なフォームでエラーの概要がない状態は重大です。
<div id="error-summary" tabindex="-1" aria-labelledby="error-heading">
<h2 id="error-heading">There are 2 errors</h2>
<ul>
<li><a href="#email">Email address: enter a valid email address</a></li>
<li><a href="#dob-day">Date of birth: enter a real date</a></li>
</ul>
</div>
- 概要はフォームの前または冒頭に配置します。送信に失敗した後に挿入し、フォーカスを移動します
- フィールドと問題の両方を特定できるリンクを使用します。リンクを有効にすると、該当するコントロールにフォーカスが移動する必要があります
- インラインのフィールドメッセージも残し、エラーが変化したときは見出しの件数を更新します
- フォーカスの移動によって明確に通知される場合は、追加のライブ通知が有用だとテストで確認されない限り、
role="alert"を追加しないでください - フォーカスの移動は送信操作への意図的な応答です。インラインのバリデーションが変化するたびにフォーカスを移動しないでください
重大:貼り付けを妨げない
入力欄で貼り付け、コピー、標準的なキーボード操作を妨げてはいけません。 貼り付けを妨げることは重大です。運動障害のあるユーザーやパスワードマネージャーを使用するユーザーは、物理的に入力できない認証情報を再入力できません。
深刻:アクセシブルな認証(WCAG 3.3.8)
適合する代替手段または支援方法がない限り、認証でユーザーに情報の記憶、操作、書き写しを求めてはいけません。最低限、以下を満たしてください。
- パスワードマネージャーがユーザー名とパスワードのフィールドを識別し、入力できるようにします
- ユーザー名、パスワード、確認コードのフィールドへのコピーと貼り付けを許可します。コード全体の貼り付けを妨げるような複数のコントロールにワンタイムコードを分割しないでください
- パスワードの特定の文字だけを尋ねないでください
- 適切なオートコンプリートトークン(
username、current-password、new-password、one-time-code)を使用します - サポートされていない書き写しや認知パズルを必要としない多要素認証の方法を用意します。アカウント復旧にもログインと同じ要件を適用してください
- CAPTCHAまたは認知テストを使用する場合は、WCAG 3.3.8 に照らして評価し、該当する代替手段を用意します
<label for="username">Email address</label>
<input id="username" name="username" type="email" autocomplete="username">
<label for="password">Password</label>
<input id="password" name="password" type="password" autocomplete="current-password">
<button type="button" aria-controls="password" aria-pressed="false">
Show password
</button>
パスワード表示ボタンは、表示ラベルと押下状態を一貫して更新し、フォーカスを維持し、入力値を消去しないようにします。
深刻:関連するコントロールのグループ化
関連するコントロールには <fieldset> と <legend> を使用します。
グループ化されていない状態は深刻です。グループラベルがないと、ラジオボタンやチェックボックスのグループが理解しにくくなります。
<fieldset>
<legend>Notification preferences</legend>
<label><input type="checkbox" name="email-notify"> Email</label>
<label><input type="checkbox" name="sms-notify"> SMS</label>
</fieldset>
<legend> は簡潔にします。見た目を整えることだけを目的に <fieldset> を使用しないでください。複数選択が可能なチェックボックスのセットでは、複数選択できることを明記します。
重大:入力タイプ
値の意味に応じて、type、autocomplete、inputmode をそれぞれ個別に選択してください。これにより、モバイル端末では適切な仮想キーボードが表示され、AT に意味が伝わります。
| 情報 | 推奨されるコントロール |
|---|---|
| メールアドレス | type="email" autocomplete="email" |
| 電話番号 | type="tel" autocomplete="tel" |
| ウェブサイトのアドレス | type="url" autocomplete="url" |
| 検索クエリ | type="search" |
| 現在のパスワード/新しいパスワード | type="password" autocomplete="current-password" / "new-password" |
| ワンタイムコード | 1 つのテキスト入力欄、autocomplete="one-time-code" inputmode="numeric" |
| 増減の意味を持つ数値の数量 | type="number" |
| 数字に見える識別子、郵便番号、カード番号 | 適切な inputmode/autocomplete を指定した type="text" |
すべての数字を数値として扱わないでください
type="number" は、数学的な演算が意味を持ち、min/max/step が有用な値にのみ使用してください。識別子や先頭にゼロが含まれる可能性のある値には使用しないでください。
<label for="quantity">Quantity</label>
<input id="quantity" name="quantity" type="number" min="1" max="20" step="1">
<label for="postal-code">Postal code</label>
<input id="postal-code" name="postal-code" type="text" autocomplete="postal-code">
inputmode は仮想キーボードを要求するものであり、値を検証するものではありません。結果として適用される制約とエラーメッセージが、受け付けるすべての値に対して適切な場合に限り、pattern を追加してください。すべてのユーザーが ASCII 数字を入力するとは限りません。
日付入力欄
ネイティブの <input type="date"> が製品のロケール、ブラウザー、AT の要件を満たす場合は使用し、実際の実装をテストしてください。生年月日のような日付には、ネイティブの日付ピッカーやカスタムカレンダーウィジェットよりも、ラベル付きのテキスト入力欄を個別に用意するほうが、理解しやすく検証もしやすいことがよくあります。
<fieldset>
<legend>Date of birth</legend>
<p id="dob-hint">For example, 23 4 1980.</p>
<label for="dob-day">Day</label>
<input id="dob-day" name="dob-day" inputmode="numeric"
autocomplete="bday-day" aria-describedby="dob-hint">
<label for="dob-month">Month</label>
<input id="dob-month" name="dob-month" inputmode="numeric" autocomplete="bday-month">
<label for="dob-year">Year</label>
<input id="dob-year" name="dob-year" inputmode="numeric" autocomplete="bday-year">
</fieldset>
ユーザーがカレンダーによる選択を必要としない限り、カスタムカレンダーダイアログを作成しないでください。必要な場合は、ダイアログ全体とグリッドのキーボード操作を実装し、テストしてください(APG の Date Picker パターンを参照)。
<select> — 単一選択
ネイティブの <select> は、すべての AT で幅広くサポートされています。適切なデフォルト値がない場合は、最初の <option> として空白のプレースホルダーオプションを必ず含めてください。
複数選択
<select multiple> は見つけにくく(Shift/Ctrl キーを押しながらクリックする必要があります)、キーボード操作にも不向きです。短く、選択肢が決まっているリストでは、<fieldset> 内のチェックボックスを優先してください。<select multiple> は熟練者向けのインターフェースでは適切な場合がありますが、対象ユーザーによるユーザビリティテストが必要です。使用する場合は、aria-describedby で関連付けた、視認できる説明(Hold Ctrl (or Cmd on Mac) to select multiple options.)を追加してください。
<datalist>
テキスト入力欄にオートコンプリート候補を表示します。ネイティブでキーボード操作に対応していますが、読み上げの品質には差があります。使用する AT の組み合わせでテストしてください。候補リストにある値だけが有効な場合、完全にアクセシブルなコンボボックスの代わりにはなりません。その場合は、APG Combobox パターンと role="combobox" を使用してください。
重大:個人データのオートコンプリート
個人データを入力するフィールドに autocomplete がないことは重大です。再入力を避けるためにオートフィルを利用する、運動障害や認知障害のあるユーザーに直接影響します。ラベル、name、type、オートコンプリートトークンは、同じ目的を示す必要があります。
<input type="text" id="name" autocomplete="name">
<input type="email" id="email" autocomplete="email">
<input type="tel" id="phone" autocomplete="tel">
<textarea id="street" autocomplete="street-address"></textarea>
<input type="text" id="city" autocomplete="address-level2">
<input type="text" id="postal" autocomplete="postal-code">
autocomplete="off" によってパスワードマネージャーやブラウザーの支援機能が無効になる、または無効になるべきだと決めつけずに、オートフィルをテストしてください。トークンの全リスト:
WCAG 1.3.5 入力目的。
重大:ボタンと送信コントロール
- すべてのボタンには、結果を説明する明確な名前を付けてください。
typeは必ず指定してください(フォーム内の<button>はデフォルトでsubmitになります) - 主要な送信操作と副次的な操作を区別してください。具体的なラベルを使える場合は、「実行」や「続行」のような曖昧なラベルを避けてください
- フォームが未入力であることだけを理由に、送信ボタンを恒久的に無効にしないでください。ユーザーが検証エラーを見つけて修正できる必要があります
- ステータス情報を削除したり、フォーカスを閉じ込めたりせずに、重複送信を防いでください
重大:非同期処理とステータスのフィードバック
- 通常の進捗や正常な完了には
aria-live="polite"/role="status"を使用し、緊急性の高い情報で待つことができない場合に限り、強い通知を使用します - 表示するステータステキストは、読み取るのに十分な時間、画面に表示し続けます
- 送信後に新しいページへ移動する場合は、移動先に内容がわかるページタイトルと見出しを用意します
- その時点で必要でない限り、キー入力のたび、文字数の変化のたび、検証状態の変化のたびに通知しないでください
非同期処理の失敗が通知されない場合は重大です — スクリーンリーダーのユーザーには、操作が完了したのか失敗したのかがわかりません。
重大:3.3.4 エラーの防止 — 法律、金融、データ
法的拘束力のある約束、金融取引、テストの回答、またはユーザーが管理するデータの変更を行うフォームでは、次のうち少なくとも1つを提供します。
- 取り消し可能 — 送信を取り消すことができます
- 確認済み — データのエラーを確認でき、ユーザーが修正できます
- 確定前に確認 — 最終送信の前に、ユーザーが内容を確認、確定、修正できます
<h2>Review your order</h2>
<dl>
<dt>Plan</dt><dd>Annual plan</dd>
<dt>Amount</dt><dd>$120.00</dd>
</dl>
<a href="/cart">Edit order</a>
<button type="submit">Confirm and pay $120.00</button>
金融や法律に関するフォームにエラー防止策がない場合は重大です。エラーを取り消せない規制対象の分野(金融サービス、法的契約、医療データ)では、致命的になる可能性があります。
重大:入力の繰り返し(WCAG 3.3.7)
検証エラーの後に、有効な情報を消去しないでください。同じ複数ステップのプロセス内では、以前に入力または提供された情報を自動入力するか、選択できるようにする必要があります。ただし、再入力が不可欠な場合、セキュリティ上必要な場合、または情報が無効になっている場合は除きます。例:「請求先住所は配送先住所と同じ」オプション、後続のステップへのアカウント識別子の引き継ぎ、検索結果ページでの検索クエリの保持などです。情報を保持しながら個人情報を保護してください — 3.3.7 は、別々のセッション間で情報を保存することを求めていません。
中程度:手順の説明
複雑な入力グループの前に簡潔な手順を示し、aria-describedby で関連付けてください。これは中程度です — 多くのユーザーは要件を推測できますが、認知障害のあるユーザーは事前の説明から恩恵を受けます。
- 手順は入力欄の後ではなく前に配置します
- 必要に応じて、形式、単位、受け付けるファイル形式、上限、英字の大文字と小文字の区別を明記します
- 必須の説明をプレースホルダーテキストやツールチップに隠さないでください
- 例だけから形式を推測するようユーザーに求めないでください
- 情報を入力・確認している間、説明を参照できるようにします
中程度:時間制限とセッションタイムアウト
不可欠な場合を除き、時間制限を避けてください(WCAG 2.2.1)。警告して延長する方式の非アクティブタイムアウトを使用する場合は、次の点に従ってください。
- 期限切れの前に警告し、簡単な操作で延長できる時間を少なくとも20秒設けます。少なくとも10回延長できるようにします
- データが失われるかどうかを説明し、警告を通知するとともに表示します
- フォーカスを正しく実装されたモーダルダイアログ内に移動し、閉じた後は元の位置にフォーカスを戻します
<dialog id="timeout-dialog" aria-labelledby="timeout-title">
<h2 id="timeout-title">Your session will expire in 2 minutes</h2>
<p>Your unsaved information will be lost.</p>
<button type="button" id="extend-session">Stay signed in</button>
<button type="button" id="sign-out">Sign out</button>
</dialog>
対応している場合は、showModal() でネイティブの <dialog> を開いてください — aria-modal だけではモーダル動作やフォーカス管理、ページの残りの部分の操作不可状態、Escape キーへの対応は実現しません。情報提供用フォームのセッションタイムアウトは中程度です。データを復元できない取引や法的な送信では致命的です。
中程度:検証のタイミング
- 少なくとも送信時に検証します
- フォーカスが外れたときのインライン検証は、直前に離れたフィールドに明確に限定されていれば問題ありません — まだ訪れていないフィールドは検証しないでください
- ユーザーが入力中の、操作を妨げるリアルタイム検証は避けてください
中程度:視覚的なレイアウトとインタラクション
- コントロール、境界線、説明、プレースホルダー、エラー、フォーカスインジケーター、無効状態のテキストと非テキストのコントラストを確保します
- 必須、無効、選択済み、成功、警告の状態を色だけで示さないでください
- 視認できるフォーカスインジケーターを用意し、320pxで横スクロールなしにリフローするようにします
- テキスト間隔の上書きによって、切り抜きや重なりが発生しないようにします
- タッチ/ポインター入力に適したターゲットサイズと間隔を確保します
- スティッキーヘッダー、仮想キーボード、検証オーバーレイによってフォーカス中のフィールドが隠れないようにします
- ユーザーにその動作が事前に伝えられていない限り、コントロールがフォーカスを受け取ったり、値が変わったりしただけでコンテキストを変更しないでください
テストの指針
- キーボード: キーボードだけで入力を完了して送信します。カスタムウィジェットは、文書化された操作方法に従ってすべて操作します。フォーカス順序が論理的であることを確認します。エラーを発生させ、エラー概要のすべてのリンクをたどります。モーダル警告がフォーカスを受け取り、終了後にフォーカスが戻ることを確認します。コピー/貼り付け/元に戻す/やり直し/パスワードマネージャーからの入力をテストします
- スクリーンリーダー/音声入力: 各コントロールの名前、ロール、状態、値、ヒント、エラーが理解できることを確認します。必須/無効の状態が読み上げられることを確認します。グループ化されたコントロールに共通の質問が含まれることを確認します。ステータスの更新が一度だけ読み上げられ、表示されたままであることを確認します。表示ラベルがアクセシブルネームに含まれることを確認します
- 拡大/リフロー/タッチ: 200%/400%のズーム、320pxのビューポート、テキスト間隔の上書き、タッチターゲットとオンスクリーンキーボード、ブラウザーの自動入力をテストします
- 検証/復旧: 空のフォーム、一部が無効なフォーム、すべてが無効なフォームを送信します。概要の順序とは異なる順序でエラーを修正します。有効な値が保持されることを確認します。サーバー側エラー、ネットワークエラー、セッションの期限切れ、重複送信をテストします
- 認証: 自動入力/パスワードマネージャーを使ってログインを完了します。パスワード全体とワンタイムコードを貼り付けます。すべてのMFA/復旧手順をテストします。後続のステップで以前に入力した情報が保持されることを確認します
自動チェックでは、名前の欠落、無効なARIA、コントラストの不備、一部の状態に関する問題を検出できますが、説明が理解しやすいか、エラーが役立つか、プロセス全体を利用できるかは判断できません。HTMLの検証、アクセシビリティツリー/アクセシブルネームのアサーション、axe-core、カスタムウィジェットのキーボード操作テスト、フォーカス配置テスト、認証フィールドの貼り付けテストを含めてください。クライアント側の検証だけでなく、サーバーがレンダリングしたエラーもテストします。
完了の定義チェックリスト
- すべてのコントロールに、プログラムで関連付けられた
<label>がある - プレースホルダーだけをラベルとして使用していない
- ネイティブ入力には
requiredを使用し、重複してaria-requiredを追加していない - 必須状態をテキストで伝えている(色だけではない)
- グループ化されたコントロールに
<fieldset>/<legend>を使用している - 個人データのフィールドに適切な
autocompleteの値を設定している - 貼り付けと標準的なキーボード操作を妨げていない
- 実行可能な場合は、
<select multiple>をチェックボックスに置き換えている - 数学的な意味またはステッパーの動作が適用される場合に限り、
type="number"を使用している - 日付入力を対象のATマトリクスでテストしている
-
<datalist>の使用をATでテストしている。制約付き入力にはAPG Comboboxパターンを使用している - 無効なフィールドに
aria-invalidを設定し、修正時に解除している - エラーメッセージが具体的で、対処方法が明確であり、
aria-describedbyで関連付けられている - エラー概要があり、送信失敗時にフォーカスを受け取る
- 非同期の成功/失敗がスクリーンリーダーに読み上げられる
- 法的/財務/データ変更フォームに、確認/修正/確定の手順がある(3.3.4)
- 複数ステップのフォームで、不要な再入力を避けている(3.3.7)
- 認証で貼り付けとパスワードマネージャーをサポートし、認知を試すパズルを避けている(3.3.8)
- セッションのタイムアウト前に、アクセシブルなネイティブ
<dialog>で警告する - いかなる状態も色だけで示していない
- キーボードとスクリーンリーダーによる一連の操作確認に合格している
主な WCAG 基準
- 1.3.1 情報と関係性(A)
- 1.3.5 入力目的の特定(AA) — 個人データのフィールドで欠けている場合は重大
- 2.2.1 タイミング調整可能(A)
- 3.3.1 エラーの特定(A) — 欠けている場合は致命的
- 3.3.2 ラベルまたは説明(A) — 欠けている場合は致命的
- 3.3.3 エラーの修正方法の提示(AA)
- 3.3.4 エラーの防止 — 法的事項、金融、データ(AA) — 欠けている場合は重大
- 3.3.7 再入力の防止(A)
- 3.3.8 アクセシブルな認証の最小要件(AA)
参考資料
- ベストプラクティスの完全ガイド
- WAI フォームチュートリアル
- WAI-ARIA APG — コンボボックスパターン
- WAI-ARIA APG — 日付選択ダイアログの例
- WCAG 1.3.5 入力目的 — autocomplete トークンの完全な一覧
- 3.3.4 エラーの防止を理解する
- 3.3.7 再入力の防止を理解する
- 3.3.8 アクセシブルな認証を理解する
基準の展望: これらのルールは WCAG 2.2 AA を対象としています。WCAG 3.0 は 開発中です。提案されている APCA コントラストモデルはエラー状態の色の 選択に影響する可能性がありますが、ラベル付け、グループ化、エラー要件は 引き継がれる見込みです。 監視先:https://www.w3.org/TR/wcag-3.0/