21. label(アクセシビリティと紐付け)
まず結論
labelで入力欄に“名前”を付けて紐付けると、クリックでフォーカスできて、読み上げでも正しく伝わるフォームになります。
最小の書き方(コピペで動く最小コード)
HTMLCode
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Label Minimum</title>
</head>
<body>
<form action="/submit" method="post">
<label for="email">メールアドレス</label>
<input id="email" name="email" type="email" autocomplete="email">
<button type="submit">送信</button>
</form>
</body>
</html>
Previewdesktop
HTMLCode
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Label Minimum</title>
</head>
<body>
<form action="/submit" method="post">
<label for="email">メールアドレス</label>
<input id="email" name="email" type="email" autocomplete="email">
<button type="submit">送信</button>
</form>
</body>
</html>
Preview を表示
重要ポイント(ここで迷いがち)
- labelは入力の“説明(名前)”
- placeholderは補助であって、ラベルの代わりにはならない
- 紐付けは for と id を一致 させる
- label for="email" / input id="email"
- ラベルをクリックすると入力欄にフォーカス
- スマホでも押しやすくなる(小さい入力欄でもOK)
- チェックボックス/ラジオは“特に”labelが重要
- 小さい丸や四角を狙わずに、文字ごとクリックできる
- 1入力につきラベルは基本1つ(迷子防止)
例で理解(よく使うパターン 5つ)
1) 基本:for/idで紐付け
HTMLCode
<label for="name">お名前</label>
<input id="name" name="name" type="text" autocomplete="name">
Previewdesktop
HTMLCode
<label for="name">お名前</label>
<input id="name" name="name" type="text" autocomplete="name">
Preview を表示
2) labelでinputを包む(for/id不要な書き方)
HTMLCode
<label>
お名前
<input name="name" type="text" autocomplete="name">
</label>
Previewdesktop
HTMLCode
<label>
お名前
<input name="name" type="text" autocomplete="name">
</label>
Preview を表示
シンプルでミスが減る一方、CSSでレイアウトするときは分けた方が楽な場合もあります。
3) チェックボックス(文字ごと押せる)
HTMLCode
<input id="agree" name="agree" type="checkbox">
<label for="agree">利用規約に同意する</label>
Previewdesktop
HTMLCode
<input id="agree" name="agree" type="checkbox">
<label for="agree">利用規約に同意する</label>
Preview を表示
4) ラジオ(選択肢をまとめて分かりやすく)
HTMLCode
<p>お支払い方法</p>
<input id="pay-card" name="pay" type="radio" value="card">
<label for="pay-card">カード</label>
<input id="pay-bank" name="pay" type="radio" value="bank">
<label for="pay-bank">銀行振込</label>
Previewdesktop
HTMLCode
<p>お支払い方法</p>
<input id="pay-card" name="pay" type="radio" value="card">
<label for="pay-card">カード</label>
<input id="pay-bank" name="pay" type="radio" value="bank">
<label for="pay-bank">銀行振込</label>
Preview を表示
5) 必須の見せ方(見た目 + 実際の必須)
HTMLCode
<label for="email">
メールアドレス <span class="req" aria-hidden="true">必須</span>
</label>
<input id="email" name="email" type="email" required>
Previewdesktop
HTMLCode
<label for="email">
メールアドレス <span class="req" aria-hidden="true">必須</span>
</label>
<input id="email" name="email" type="email" required>
Preview を表示
見た目の「必須」はaria-hidden="true"で読み上げを邪魔しにくくしつつ、実際はrequiredで必須に。
使い分け(似た要素/属性との違い)
label vs placeholder
- label:入力の名前(常に残る・読み上げで伝わる)
- placeholder:入力例(入力中に消える・ラベル代わりにしない)
label vs aria-label
- 画面に見せられるなら labelが基本
- どうしても文字を置けない(アイコンのみ等)→ aria-label を検討
for/id方式 vs 包む方式
- for/id:構造が分かりやすく、CSSで並べやすい
- 包む:最短で書けてミスが減る
実務のコツ(SEO/安全/アクセシビリティ)
- 入力の目的が一目で分かる文言に
×「入力」→ ○「メールアドレス」「電話番号」 - チェック/ラジオは“ラベルを大きく”
文字をクリックできるだけでミスが激減する - エラー文は入力の近くに置く(実務で重要)
まずはHTML段階では「どの入力が何か」をlabelで確実にするのが第一歩 - idはユニーク(#15)
for/id方式を使うなら特に、重複は事故の元
NG・禁止例(事故る書き方)
NG1)labelが無く、placeholderだけ
HTMLCode
<input name="email" type="email" placeholder="メールアドレス">
Previewdesktop
HTMLCode
<input name="email" type="email" placeholder="メールアドレス">
Preview を表示
✅ 正:labelを付ける
HTMLCode
<label for="email">メールアドレス</label>
<input id="email" name="email" type="email" placeholder="example@domain.com">
Previewdesktop
HTMLCode
<label for="email">メールアドレス</label>
<input id="email" name="email" type="email" placeholder="example@domain.com">
Preview を表示
NG2)forとidが一致していない(紐付かない)
HTMLCode
<label for="mail">メール</label>
<input id="email" name="email" type="email">
Previewdesktop
HTMLCode
<label for="mail">メール</label>
<input id="email" name="email" type="email">
Preview を表示
✅ 正:一致させる
HTMLCode
<label for="email">メール</label>
<input id="email" name="email" type="email">
Previewdesktop
HTMLCode
<label for="email">メール</label>
<input id="email" name="email" type="email">
Preview を表示
NG3)同じidを複数に使う(紐付けが壊れる)
HTMLCode
<input id="email" name="email" type="email">
<input id="email" name="backup_email" type="email">
Previewdesktop
HTMLCode
<input id="email" name="email" type="email">
<input id="email" name="backup_email" type="email">
Preview を表示
✅ 正:idは別々に
HTMLCode
<input id="email" name="email" type="email">
<input id="email2" name="backup_email" type="email">
Previewdesktop
HTMLCode
<input id="email" name="email" type="email">
<input id="email2" name="backup_email" type="email">
Preview を表示
NG4)“必須”の表示だけでrequiredが無い
HTMLCode
<label for="email">メール(必須)</label>
<input id="email" name="email" type="email">
Previewdesktop
HTMLCode
<label for="email">メール(必須)</label>
<input id="email" name="email" type="email">
Preview を表示
✅ 正:実際の必須も付ける
HTMLCode
<label for="email">メール</label>
<input id="email" name="email" type="email" required>
Previewdesktop
HTMLCode
<label for="email">メール</label>
<input id="email" name="email" type="email" required>
Preview を表示
見た目を整える(HTML+CSSセット:5例)
色は使わず、余白・線・影・フォーカスで整えます。
例1)縦並び(基本)
例1)縦並び(基本)
HTMLCode
<div class="field">
<label class="field__label" for="name1">お名前</label>
<input class="field__input" id="name1" name="name" type="text" autocomplete="name" />
</div>CSSCode
.field{ display: grid; gap: .35rem; max-width: 520px; }
.field__label{ font-size: .95rem; }
.field__input{
padding: .75rem .9rem;
border: 1px solid rgba(0,0,0,.25);
border-radius: 14px;
box-shadow: 0 10px 22px rgba(0,0,0,.06);
}
.field__input:focus{
outline: 2px solid currentColor;
outline-offset: 2px;
}Previewdesktop
HTMLCode
<div class="field">
<label class="field__label" for="name1">お名前</label>
<input class="field__input" id="name1" name="name" type="text" autocomplete="name" />
</div>CSSCode
.field{ display: grid; gap: .35rem; max-width: 520px; }
.field__label{ font-size: .95rem; }
.field__input{
padding: .75rem .9rem;
border: 1px solid rgba(0,0,0,.25);
border-radius: 14px;
box-shadow: 0 10px 22px rgba(0,0,0,.06);
}
.field__input:focus{
outline: 2px solid currentColor;
outline-offset: 2px;
}Preview を表示
例2)横並び(PCでラベル列を揃える)
例2)横並び(PCでラベル列を揃える)
HTMLCode
<div class="row">
<label class="row__label" for="email2">メール</label>
<input class="row__input" id="email2" name="email" type="email" autocomplete="email" />
</div>CSSCode
.row{ display: grid; gap: .35rem; align-items: center; }
@media (min-width: 760px){
.row{ grid-template-columns: 160px 1fr; gap: .8rem; }
}
.row__input{
padding: .75rem .9rem;
border: 1px solid rgba(0,0,0,.25);
border-radius: 14px;
}
.row__input:focus{
outline: 2px solid currentColor;
outline-offset: 2px;
}Previewdesktop
HTMLCode
<div class="row">
<label class="row__label" for="email2">メール</label>
<input class="row__input" id="email2" name="email" type="email" autocomplete="email" />
</div>CSSCode
.row{ display: grid; gap: .35rem; align-items: center; }
@media (min-width: 760px){
.row{ grid-template-columns: 160px 1fr; gap: .8rem; }
}
.row__input{
padding: .75rem .9rem;
border: 1px solid rgba(0,0,0,.25);
border-radius: 14px;
}
.row__input:focus{
outline: 2px solid currentColor;
outline-offset: 2px;
}Preview を表示
例3)チェックボックスを“押しやすく”
例3)チェックボックスを“押しやすく”
HTMLCode
<div class="check">
<input class="check__box" id="agree3" name="agree" type="checkbox" />
<label class="check__label" for="agree3">利用規約に同意する</label>
</div>CSSCode
.check{
display: flex;
gap: .6rem;
align-items: flex-start;
padding: .7rem .9rem;
border: 1px solid rgba(0,0,0,.18);
border-radius: 16px;
}
.check__box{ width: 18px; height: 18px; margin-top: .2rem; }
.check__label{ line-height: 1.6; cursor: pointer; }Previewdesktop
HTMLCode
<div class="check">
<input class="check__box" id="agree3" name="agree" type="checkbox" />
<label class="check__label" for="agree3">利用規約に同意する</label>
</div>CSSCode
.check{
display: flex;
gap: .6rem;
align-items: flex-start;
padding: .7rem .9rem;
border: 1px solid rgba(0,0,0,.18);
border-radius: 16px;
}
.check__box{ width: 18px; height: 18px; margin-top: .2rem; }
.check__label{ line-height: 1.6; cursor: pointer; }Preview を表示
例4)必須バッジ(見た目だけ・読み上げ邪魔しにくい)
例4)必須バッジ(見た目だけ・読み上げ邪魔しにくい)
HTMLCode
<div class="field">
<label class="field__label" for="email4">
メールアドレス <span class="req" aria-hidden="true">必須</span>
</label>
<input class="field__input" id="email4" name="email" type="email" required />
</div>CSSCode
.field{ display: grid; gap: .35rem; max-width: 520px; }
.field__label{ font-size: .95rem; }
.field__input{
padding: .75rem .9rem;
border: 1px solid rgba(0,0,0,.25);
border-radius: 14px;
box-shadow: 0 10px 22px rgba(0,0,0,.06);
}
.field__input:focus{
outline: 2px solid currentColor;
outline-offset: 2px;
}
.req{
display: inline-block;
padding: .1rem .45rem;
border: 1px solid currentColor;
border-radius: 999px;
font-size: .8rem;
margin-left: .4rem;
opacity: .8;
}Previewdesktop
HTMLCode
<div class="field">
<label class="field__label" for="email4">
メールアドレス <span class="req" aria-hidden="true">必須</span>
</label>
<input class="field__input" id="email4" name="email" type="email" required />
</div>CSSCode
.field{ display: grid; gap: .35rem; max-width: 520px; }
.field__label{ font-size: .95rem; }
.field__input{
padding: .75rem .9rem;
border: 1px solid rgba(0,0,0,.25);
border-radius: 14px;
box-shadow: 0 10px 22px rgba(0,0,0,.06);
}
.field__input:focus{
outline: 2px solid currentColor;
outline-offset: 2px;
}
.req{
display: inline-block;
padding: .1rem .45rem;
border: 1px solid currentColor;
border-radius: 999px;
font-size: .8rem;
margin-left: .4rem;
opacity: .8;
}Preview を表示
例5)“説明文”を追加(ラベル + 補足)
例5)“説明文”を追加(ラベル + 補足)
HTMLCode
<div class="field">
<label class="field__label" for="tel5">電話番号</label>
<p class="help" id="tel-help5">ハイフンなしで入力してください。</p>
<input class="field__input" id="tel5" name="tel" type="tel" aria-describedby="tel-help5" autocomplete="tel" />
</div>CSSCode
.field{ display: grid; gap: .35rem; max-width: 520px; }
.field__label{ font-size: .95rem; }
.help{ margin: 0; font-size: .9rem; opacity: .85; line-height: 1.6; }
.field__input{
padding: .75rem .9rem;
border: 1px solid rgba(0,0,0,.25);
border-radius: 14px;
box-shadow: 0 10px 22px rgba(0,0,0,.06);
}
.field__input:focus{
outline: 2px solid currentColor;
outline-offset: 2px;
}Previewdesktop
HTMLCode
<div class="field">
<label class="field__label" for="tel5">電話番号</label>
<p class="help" id="tel-help5">ハイフンなしで入力してください。</p>
<input class="field__input" id="tel5" name="tel" type="tel" aria-describedby="tel-help5" autocomplete="tel" />
</div>CSSCode
.field{ display: grid; gap: .35rem; max-width: 520px; }
.field__label{ font-size: .95rem; }
.help{ margin: 0; font-size: .9rem; opacity: .85; line-height: 1.6; }
.field__input{
padding: .75rem .9rem;
border: 1px solid rgba(0,0,0,.25);
border-radius: 14px;
box-shadow: 0 10px 22px rgba(0,0,0,.06);
}
.field__input:focus{
outline: 2px solid currentColor;
outline-offset: 2px;
}Preview を表示
aria-describedbyで補足説明も紐付けできます(便利だけど、まずはlabelを確実に!)。
理解チェック(3問・答え付き)
Q. labelとinputを紐付けるために一致させるのは?
A. label for と input id。
Q. placeholderはlabelの代わりになる?
A. ならない(補助)。
Q. チェックボックスでlabelが特に大事な理由は?
A. 小さいチェック部分を狙わず、文字ごとクリックできるから。
ミニ演習(すぐ試せる小課題 2つ)
-
「メールアドレス」と「パスワード」の2項目を作り、for/id方式で正しく紐付けてください(クリックでフォーカスできるのを確認)。
-
「利用規約に同意する」チェックボックスを作り、CSS例3を当てて“押しやすいチェック行”にしてください(文字クリックでもON/OFFできればOK)。