label 要素の役割
<label> はフォームの入力欄に名前を付けます。for に入力欄の id を指定して関連付けると、2 つのことが起きます。入力欄にフォーカスするとスクリーンリーダーがラベルを読み上げ、ラベルのテキストをクリックすると入力欄にフォーカスが移ります。下の 2 つのテキストをクリックしてみてください。
「City」をクリックすると、その入力欄にカーソルが入ります。「Country」をクリックしても何も起きず、2 つ目の入力欄にフォーカスしたスクリーンリーダーには名前のない「テキスト編集」としか聞こえません。2 つは見た目が同じでも、ラベルが付いているのは片方だけです。
ラベルを関連付ける 2 つの方法
for と id を使うか、入力欄をラベルの中に入れます。
for と id | 囲む | |
|---|---|---|
id が必要か | 必要。ページ内で一意 | 不要 |
| ラベルと入力欄を離して置けるか | 置ける (表のセル、グリッド) | 置けない。入力欄は中にある |
| 壊れやすい原因 | 打ち間違いや id の重複 | 1 つのラベルに 2 つの入力欄を入れる |
for は入力欄の name ではなく id と一致する必要があります。2 つは同じ単語であることが多いので、誰かが片方を変えるまで間違いに気づきません。両方 (囲んだうえで for) を使うのも問題なく、よく行われています。
ラベルを関連付けられるのは、<input> (type="hidden" を除く)、<select>、<textarea>、<button>、<meter>、<output>、<progress> です。1 つのラベルは 1 つの入力欄に名前を付けます。1 つの入力欄に複数のラベルを付けることもできますが、わかりやすいラベル 1 つのほうが誰にとっても使いやすいです。
チェックボックスとラジオボタンのクリック範囲を広げる
小さな部品ほどラベルが重要になります。ラベルのどこをクリックしても箱が切り替わるので、クリックできる範囲が 13 ピクセルの四角ではなくテキストの行全体になります。ラベルにスタイルを付ければ、範囲をさらに広げられます。
箱から離れた、各行の padding の部分をクリックしてみてください。1 行目は切り替わりますが、2 行目は箱そのものを押さない限り何も起きません。チェックボックスについては HTML のチェックボックス で詳しく解説しています。
ヒントとエラーメッセージ
ラベルは短く、入力欄の名前だけにしましょう。追加の説明やエラーメッセージは別の要素に書いて aria-describedby で関連付けると、スクリーンリーダーはまずラベルを、その後に説明を読み上げます。
入力欄を空のまま、次に AB、次に ada99 で Create を押してみてください。aria-describedby があると、スクリーンリーダーは「Username、必須、テキスト編集、3 to 16 lowercase letters or digits、Enter a username.」のように読み上げます。required 属性がすでに「必須」と伝えているので、アスタリスクは aria-hidden にしています。「アスタリスク」と聞こえても何の情報にもなりません。
非表示のラベル
検索ボタンの横の検索ボックスのように、テキストのラベル以外に見た目の手がかりがある入力欄もあります。それでもラベルは必要です。見た目だけ隠して、スクリーンリーダーのためにページには残しましょう。
display: none や visibility: hidden で隠してはいけません。スクリーンリーダーからも隠れてしまい、すべてのブラウザとスクリーンリーダーが隠れたラベルを名前として使い続けるわけではありません。もう 1 つの方法は input に aria-label="Search courses" を付けることで、label 要素なしで名前を付けられます。それでも、場所があるなら見えるラベルが最善です。入力欄が何のためのものかが見えれば、誰にとっても役に立ちます。
よくある間違い
forがidではなくnameを指している。 何も関連付けられません。- id の重複。
forはその id を持つ最初の要素に関連付けられ、それがページ上の別のフォームの入力欄かもしれません。 - ラベルの代わりにプレースホルダーを使う。 入力すると消え、確実な名前になりません。
- 1 つのラベルの中に 2 つの入力欄を入れる。 ラベルが名前を付けるのは 1 つだけで、2 つ目にはラベルがなくなります。
- チェックボックスのラベルの中にリンクを置く。 たとえば「利用規約」の部分がリンクになった「利用規約に同意する」です。行の一部は箱を切り替え、一部はページを開くので、間違えて押しやすくなります。リンクはラベルの外に置きましょう。
- ラベルを
display: noneで隠す。 見た目だけ隠すクラスを使いましょう。 - 入力欄の横のテキストが
<label>になっていない。 見た目は同じでも何もしません。入力欄を囲むフォームについては HTML のフォーム を参照してください。
よくある質問
HTML の label タグは何をしますか?
フォームの入力欄に名前を付けます。入力欄にフォーカスするとスクリーンリーダーがラベルを読み上げ、ラベルをクリックすると入力欄にフォーカスが移ります。チェックボックスやラジオボタンなら切り替わります。
label の for 属性とは何ですか?
for には、ラベルが属する入力欄の id を書きます: <label for="email">Email</label> <input id="email">。name ではなく id と完全に一致する必要があります。
input は label の中に入れるべきですか、for を使うべきですか?
現在のブラウザとスクリーンリーダーではどちらでも動きます。囲む方法なら id は不要です。for と id なら、別々の表のセルのように、マークアップ上でラベルと入力欄を離して置けます。囲んだうえで for も付けるチームも多くあります。
プレースホルダーはラベルの代わりになりますか?
なりません。プレースホルダーは読者が入力を始めると消え、コントラストが低いことが多く、入力欄の名前として確実に読み上げられるわけでもありません。見える <label> を使い、プレースホルダーは使うとしても入力例に留めましょう。
ラベルを非表示にしつつスクリーンリーダーには残すには?
<label> は残し、スクリーンリーダーからも隠れてしまう display: none ではなく、1 ピクセルに縮めて切り取るクラスで見た目だけ隠します。ラベルを置く場所がまったくない入力欄なら、入力欄に aria-label を付ける方法もあります。