TT Lab
はじめる
学ぶ 学習パス コース

HTML — タグ一つが機能を肩代わりする

名前のない入力欄をなくす

TT Labで続きを見る

目標

サインアップフォームを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も一緒に出力します。

ステップ

  1. ドキュメントの骨組みとform・送信ボタン
  2. 入力欄3つ・名前がlabelから来るように
  3. ラジオのグループ・fieldsetとlegend
  4. ルールの案内をaria-describedbyで
  5. エラー状態: aria-invalidとrole="alert"
  6. typeとautocomplete
  7. 必須表示: 目でも、プログラムでも
  8. 計算ツールの結果を08-names.txtに
  9. まとめ → 09-notes.md

参考

フォーム一式を立ち上げる

/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つです。関連付けは文字ではなく、計算です。どんなミスが「マークアップは問題なく見えるのに名前がない」状態を作るのかを、自分の言葉で書いておくと、次は手が覚えています。