入力フォームを作っていると、「お支払い方法」や「住所」など、関連する入力欄をひとつのまとまりとして見せたい場面があります。そんなときに使うのが <fieldset> と <legend> です。<fieldset> で関連する入力欄を囲み、<legend> でそのグループの見出しを付けることで、見た目だけでなく文書の構造としても「ここはひとまとまり」だと示せます。この記事では、基本の書き方からアクセシビリティ上の意味、ラジオボタン群での実践例、disabled による一括無効化、CSS での見た目の調整までを、HTML を学び始めた方に向けて解説します。
目次
fieldsetとlegendの役割
<fieldset> は、フォームの中で関連する入力欄をひとまとめにグループ化するための要素です。たとえば「氏名・郵便番号・住所」をまとめて「お届け先」のグループにする、といった使い方をします。<legend> は、その <fieldset> グループに付ける見出し(タイトル)を表します。
この2つはセットで使います。<fieldset> だけでもグループ化はできますが、<legend> で名前を付けることで、「このまとまりが何のグループなのか」が人にも支援技術にも伝わります。1つの長いフォームを意味のあるブロックに分けて整理できるのが、この要素のいちばんの役割です。
基本の書き方
もっとも基本的な形は、<fieldset> で入力欄を囲み、その最初の子要素として <legend> を置く、というものです。<legend> は必ず <fieldset> の先頭に書く、というのが重要なルールです。
<form>
<fieldset>
<legend>お届け先</legend>
<label for="name">氏名</label>
<input type="text" id="name" name="name">
<label for="zip">郵便番号</label>
<input type="text" id="zip" name="zip">
<label for="addr">住所</label>
<input type="text" id="addr" name="addr">
</fieldset>
</form>
このように書くと、ブラウザの既定スタイルでは入力欄全体が枠線で囲まれ、その枠の左上に「お届け先」という見出しが乗ったように表示されます。<legend> を <fieldset> の途中や末尾に置くと正しく表示されないため、必ず先頭に置きましょう。
なぜグループ化するのか
見た目を整えるだけなら <div> と見出しでも作れます。それでも <fieldset> と <legend> を使う理由は、アクセシビリティにあります。スクリーンリーダー(画面の内容を読み上げる支援技術)は、<fieldset> でまとめられた入力欄を読み上げるとき、<legend> の内容をグループ名として一緒に読み上げます。
これが特に効くのが、ラジオボタンやチェックボックスの集まりです。たとえば「はい/いいえ」のラジオボタンだけを読み上げられても、何に対する「はい/いいえ」なのか分かりません。<legend> に「メールマガジンを受け取りますか?」と書いておけば、「メールマガジンを受け取りますか? はい」のように、質問とセットで読み上げられます。目で見ればすぐ分かる対応関係を、画面を見られない人にも正しく伝えられるわけです。
ラジオボタン群を囲む実践例
では、実際にラジオボタン群を <fieldset> と <legend> で囲んでみます。次のデモは「お支払い方法」を選ぶフォームです。CSS は <fieldset> の既定の枠線をそのまま使い、<legend> を太字にしただけのシンプルなものです。HTML / CSS タブを切り替えると、コードと表示の対応を確認できます。
<form>
<fieldset>
<legend>お支払い方法</legend>
<label><input type="radio" name="pay" value="card" checked> クレジットカード</label>
<label><input type="radio" name="pay" value="bank"> 銀行振込</label>
<label><input type="radio" name="pay" value="cod"> 代金引換</label>
</fieldset>
</form>
form {
font-family: sans-serif;
max-width: 360px;
}
/* fieldset の既定の枠線。legend は枠線の途切れた位置に表示される */
fieldset {
border: 1px solid #999;
}
legend {
font-weight: bold;
}
label {
display: block;
padding: 4px 0;
}
ポイントは、3つのラジオボタンに同じ name="pay" を付けて1つのグループにしていることと、それらをまとめて <fieldset> で囲み、<legend> に「お支払い方法」という質問の見出しを付けていることです。これで「どの設問に対する選択肢なのか」が、見た目にも構造にもはっきりします。
disabledでまとめて無効化する
<fieldset> には便利な性質があります。disabled 属性を <fieldset> に付けると、その中にあるすべての入力欄がまとめて無効(操作不可)になります。入力欄を1つずつ無効化しなくても、グループごと一括で切り替えられるということです。
<!-- fieldset に disabled を付けると中の入力欄がすべて無効になる -->
<fieldset disabled>
<legend>クーポン(現在利用できません)</legend>
<label for="coupon">クーポンコード</label>
<input type="text" id="coupon" name="coupon">
<button type="button">適用</button>
</fieldset>
「ログインしている間だけ入力できるようにする」「特定の条件を満たすまで一時的に触れないようにする」といった場面で役立ちます。JavaScript から fieldset.disabled = true のように切り替えれば、グループ全体の有効・無効をまとめて制御できます。なお、無効になった入力欄の値はフォーム送信時に送られない点も覚えておくとよいでしょう。
CSSで見た目を整える
<fieldset> はブラウザの既定で枠線(border)が付き、<legend> はその枠線の上に重なるように配置されます。この既定スタイルが好みでなければ、CSS で自由に上書きできます。次のデモでは、既定の枠線を角丸の青い枠に変え、<legend> に背景色を付けてラベルらしく見せています。
<form>
<fieldset class="card">
<legend>配送オプション</legend>
<label><input type="radio" name="ship" value="normal" checked> 通常配送(無料)</label>
<label><input type="radio" name="ship" value="express"> お急ぎ便(+500円)</label>
<label><input type="radio" name="ship" value="time"> 日時指定便(+300円)</label>
</fieldset>
</form>
form {
font-family: sans-serif;
max-width: 360px;
}
/* 既定の枠線を消して角丸の枠に整える */
.card {
border: 2px solid #007bff;
border-radius: 8px;
padding: 16px 20px;
}
/* legend に背景と余白を付けて見出しらしく見せる */
.card legend {
padding: 2px 10px;
background: #007bff;
color: #fff;
border-radius: 4px;
font-size: 14px;
}
.card label {
display: block;
padding: 6px 0;
}
枠線を完全に消したい場合は border: none を指定します。<legend> の位置を動かしたいときは、margin や padding で調整するのが手軽です。位置調整に position を使う方法もありますが、まずは余白で整える範囲で十分なケースがほとんどです。デザインを変えても、グループ化という構造上の意味は失われない点が、<fieldset> を使う利点です。
使うときに押さえておきたい属性
<fieldset> で使う主な属性を整理しておきます。グループ化そのものに属性は必須ではありませんが、フォームを組み立てるうえで知っておくと便利です。
| 属性 | 付ける要素 | 説明 |
|---|---|---|
disabled | <fieldset> | 中のすべての入力欄をまとめて無効化する。無効な入力欄の値は送信されない |
form | <fieldset> | 離れた場所にある <form> の id を指定し、その一部として関連付ける |
name | <fieldset> | スクリプトから参照するための名前。送信データには含まれない |
一方で <legend> には特別な属性はなく、グループの見出しとなるテキストを入れるだけのシンプルな要素です。役割が明確なので、迷うことは少ないでしょう。
legendが正しく表示されないとき
legendがfieldsetの先頭にあるか確認する
<legend> が枠線の上にうまく乗らない、見出しとして表示されない、という場合、まず疑うのは配置です。<legend> は <fieldset> の最初の子要素でなければなりません。間に <div> やテキストが入っていたり、<legend> がグループの途中・末尾にあると、ブラウザは通常の要素として扱い、見出しらしい表示になりません。
fieldsetの外にlegendを置いていないか
<legend> は <fieldset> の中でしか意味を持ちません。<fieldset> の外側に置くと、グループの見出しとしては機能せず、スクリーンリーダーにもグループ名として伝わりません。グループ化が目的であれば、必ず <fieldset> で囲んだ内側の先頭に <legend> を置くようにします。
まとめ
<fieldset> は関連する入力欄をひとまとまりにグループ化する要素で、<legend> はそのグループの見出しを表します。<legend> は <fieldset> の最初の子要素として置くのが必須のルールです。見た目を整えるだけでなく、スクリーンリーダーがグループ名を読み上げてくれるため、特にラジオボタンやチェックボックスの集まりではアクセシビリティ上の効果が大きくなります。disabled を付ければグループ全体をまとめて無効化でき、枠線や <legend> の見た目も CSS で自由に調整できます。フォームを意味のあるまとまりに整理したいときに、ぜひ活用してください。