名前のない入力欄をなくす
目標
サインアップフォームを1つ書き、すべての入力欄にアクセシブルネームが実際に計算されるかを確認します。ブラウザーはありませんが、名前の計算はマークアップだけで答えが1つに決まります。
なぜ重要なのか
「labelを書いたか」は目で数えられますが、それではforとidが食い違っている入力欄を検出できません。機械が見るのは文字ではなく計算結果であり、その計算には決まった順序があります。aria-labelledby → aria-label → label → title → placeholderです。
前の段階が値を出せば、後ろは見ません。そのため、aria-label1つが、目に見えるlabelをまるごと上書きし、画面に書かれた文字と音声が分かれます。音声で操作するユーザーは、見えている文字を呼ぶため、その瞬間に操作ができなくなります。
作るもの
/root/work/forms/signup.htmlの1つだけです。CSSもJavaScriptも必要ありません。このラボが見るのは、関連付けが成立しているかです。
計算ツール
cd /root/work/forms
python3 /opt/lab/checks/html-form-lab/accname.py signup.html
入力欄ごとに、名前とその名前がどこから来たのかを表示します。切れているaria-labelledbyとaria-describedbyも一緒に出力します。
ステップ
- ドキュメントの骨組みと
form・送信ボタン - 入力欄3つ・名前が
labelから来るように - ラジオのグループ・
fieldsetとlegend - ルールの案内を
aria-describedbyで - エラー状態:
aria-invalidとrole="alert" typeとautocomplete- 必須表示: 目でも、プログラムでも
- 計算ツールの結果を
08-names.txtに - まとめ →
09-notes.md
参考
- フォームの送信先は実際になくても構いません。マークアップだけを見ます。
idが重複すると、関連付けがすべて最初の要素にだけ向かいます。採点ツールが先に弾きます。- 自動検査は、問題の一部しか検出しません。残りは、マウスをどけてTabキーだけでフォームを最後まで入力してみると、ほとんどが明らかになります。
フォーム一式を立ち上げる
/root/work/forms/signup.htmlを作成してください。<!doctype html>、<html lang="ko">、<title>、<meta charset>、<meta name="viewport">が必要で、actionとmethodを持つ<form>の中に、入力欄1つと送信用の<button>が必要です。
mkdir -p /root/work/formsを実行します。actionとmethodを書いておけば、JavaScriptが動かなくなってもフォームは送信されます。それがフォームのデフォルトです。送信はbuttonで行ってください。input type="submit"でも構いませんが、ボタンの中にアイコンやほかの要素を入れられません。
名前がどこから来るのか
入力欄を3つ以上に増やし、すべての入力欄の名前がlabelから来るようにしてください。計算ツールが出力する출처=(韓国語で「出どころ」を意味する語です)が、3つの欄すべてでlabelである必要があります。placeholderやtitleで名前を済ませると失敗します。
labelのforと入力欄のidは、1文字も違ってはいけません。目では並んでくっついているように見えても、機械にとっては赤の他人です。python3 /opt/lab/checks/html-form-lab/accname.py signup.htmlを実行して、いま名前がどこから来ているかを先に確認してください。
グループにはグループの名前がある
同じnameを持つラジオボタンを2つ以上作成し、1つの<fieldset>の中に入れたうえで、<legend>でグループ名を付けてください。各ラジオにも、それぞれのlabelが必要です。
ラジオは、複数が集まって1つの質問を成します。選択肢ごとに名前があっても、「何を選んでいる最中なのか」はどこにもありません。その場所をlegendが埋めます。nameが同じだと、一方を選んだときに他方が解除されます。
ルールは名前ではなく説明
パスワードのルールの案内を別の要素として書き、aria-describedbyで関連付けてください。説明の文章は10文字以上で、名前と同じ文であってはいけません。
ルールをlabelの中に押し込むと、入力欄の名前が「パスワード、12文字以上、数字と記号を…」になってしまいます。名前は短くないと、一覧から選べません。長い案内は、説明として分離してください。
エラーをプログラムが読めるようにする
メール欄にaria-invalid="true"を指定し、ヘルプとエラーメッセージの2つの要素をaria-describedbyにスペースで並べてください。エラーメッセージの要素にはrole="alert"を付けます。
赤い枠線は、色を区別できない人にとっては何でもありません。aria-describedbyは複数のidを受け取ります。エラーが表示されてもルールの案内が消えないように、両方を指してください。あとから現れる文字は、role="alert"がないと読み上げられません。
タイプの回数もアクセシビリティ
文字を入力する欄を4つに増やし(連絡先の欄を追加してください)、すべてに標準のautocompleteの値を指定してください。メール欄はtype="email"とautocomplete="email"、パスワードはnew-passwordです。
HTML標準のautofillのフィールド名の一覧にない値は、ブラウザーが単に無視します。e-mailは何も行いません。サインアップはnew-password、ログインはcurrent-passwordです。この区別があって初めて、パスワードマネージャーが新しいパスワードを提案します。
必須は目でも見えるように
2つ以上の欄にrequiredを指定し、その欄のlabelの文字にも必須の表示を入れてください。任意の欄は1つ以上残しておく必要があり、任意の欄の名前には必須の表示があってはいけません。
aria-requiredだけを使うと、知らせるだけで、ブラウザーの送信ブロックは有効になりません。逆にrequiredだけを使うと、目では、どの欄が必須なのかわかりません。両方が必要です。すべてを必須にすると、表示が何も区別してくれません。
計算ツールで確認する
accname.pyを実行して、結果を/root/work/forms/08-names.txtに残してください。保存された行数が現在のドキュメントのコントロール数と同じで、출처=placeholder(韓国語で「出どころ」を意味する語を含みます)や、切れた参照の警告がない必要があります。
python3 /opt/lab/checks/html-form-lab/accname.py signup.html | tee 08-names.txtを実行します。ドキュメントを直したら、保存し直す必要があります。採点ツールが、保存したものと現在のドキュメントを突き合わせます。
何が関連付けで、何が文字なのか
/root/work/forms/09-notes.mdに3行以上(120文字以上)書いてください。本文にplaceholder、fieldset、이름が含まれている必要があります(韓国語で「名前」を意味する語を含みます)。ドキュメント自体も、引き続きステップ2の基準を通過する必要があります。
核心は1つです。関連付けは文字ではなく、計算です。どんなミスが「マークアップは問題なく見えるのに名前がない」状態を作るのかを、自分の言葉で書いておくと、次は手が覚えています。