HTMLのfieldset・legendタグとは?フォーム項目をグループ化する書き方を初心者向けに解説

fieldset・legendの基本。関連するフォーム項目をグループ化する

「メール」「電話」という選択肢だけを並べても、何について選ぶのかは伝わりません。フォームの項目が増えたら、個々の項目名に加えて、まとまり全体の見出しを用意すると理解しやすくなります。

<fieldset>タグは関連するフォーム項目を一つのグループにし、<legend>タグはそのグループの見出しを示します。複数の項目に共通する質問や見出しがあるとき、fieldsetで囲み、先頭にlegendを書くのが基本です。

この記事では、fieldset・legend・labelの役割を分けて考え、グループ化が必要な場面と書き方を解説します。後半の練習コードをHTMLファイルとして開けば、選択肢の文字から操作できることと、選んだ値が送信対象になることまで確かめられます。

この記事で分かること
  • fieldset・legendタグの役割と基本構造
  • fieldset・legend・label・divの違い
  • radio・checkbox・住所入力をまとめる書き方
  • disabled・name・form属性の注意点
  • fieldsetを使うか迷ったときの判断方法
目次

fieldset・legendタグの役割

<fieldset>は、関連する入力欄や選択肢を一つのまとまりにするHTML要素です。<legend>は、そのまとまりに付ける見出しです。入力欄・選択肢などのフォーム部品は「コントロール」、見出しや説明は「キャプション」と呼ばれることもあります。

<fieldset>
  <legend>希望する連絡方法</legend>

  <input type="radio" id="contact-email" name="contact_method" value="email">
  <label for="contact-email">メール</label>

  <input type="radio" id="contact-phone" name="contact_method" value="phone">
  <label for="contact-phone">電話</label>
</fieldset>

この例では、「希望する連絡方法」がグループ全体の見出しで、「メール」「電話」が各radioの項目名です。MDNのfieldset要素リファレンスでも、複数のコントロールとlabelをウェブフォーム内でグループ化する要素として説明されています。

fieldsetタグの役割

fieldsetは、関連するフォーム部品を意味のある単位で囲みます。たとえば「配送先住所」と「請求先住所」、「希望する連絡方法」、「興味のある分野」のように、一つの共有見出しで説明できる項目群に向いています。

ブラウザーは通常、fieldsetの周囲へ枠線を表示します。ただし、枠線は見た目の初期表示にすぎません。fieldsetを使う主目的は、項目同士の意味上の関係をHTMLへ表すことです。

legendタグの役割

legendは、親のfieldsetへ付ける見出しです。<legend>配送先住所</legend>と書けば、その後に続く郵便番号や住所が配送先の情報であることを示せます。

MDNのlegend要素リファレンスでは、legendを親fieldsetの内容に対するキャプションとして定義しています。legendは単独で使わず、fieldsetの内側で使います。

グループ名が利用者へ伝わる仕組み

関連項目をfieldsetとlegendで分けると、画面を見る人はフォームを小さな単位で読み進められます。画面の文字や部品の意味を音声で伝える読み上げソフトなどにも、グループ名と各項目の関係を示せます。読み上げ方はソフトやブラウザーの組み合わせで異なるため、同じ順序で必ず読まれるという意味ではありません。

W3C WAIのフォームコントロールをグループ化する解説でも、関連する項目をグループ化し、fieldset内の最初の要素としてlegendを置く方法が案内されています。

fieldset・legendタグの基本の書き方

最小構造は、fieldsetで関連項目を囲み、その先頭へlegendを置く形です。

<fieldset>
  <legend>配送先住所</legend>

  <label for="postal-code">郵便番号</label>
  <input type="text" id="postal-code" name="postal_code">

  <label for="address">住所</label>
  <input type="text" id="address" name="address">
</fieldset>

legendを書く位置

legendは、fieldset直下の最初の子要素として書きます。改行や空白はあっても構いませんが、divや入力欄より前にlegendを置くのが基本です。

<fieldset>
  <legend>配送先住所</legend>
  <!-- 関連するlabelと入力欄 -->
</fieldset>

WCAGのTechnique H71でも、fieldsetの内側でlegendを最初の要素にする方法が示されています。

legendと各項目のlabel

legendはグループ全体の見出しであり、各入力欄の項目名ではありません。fieldsetとlegendを使っても、input・select・textareaにはそれぞれ分かるlabelを付けます。

たとえば「配送先住所」というlegendだけでは、二つの入力欄のどちらが郵便番号で、どちらが住所なのか区別できません。「郵便番号」「住所」のlabelも必要です。

fieldset・legend・labelの親子関係

fieldsetを外側の箱、legendを箱全体の見出し、labelとフォーム部品を箱の中の個別項目と考えると理解しやすくなります。

fieldsetで配送先の項目を囲み、legendでグループ名、labelで郵便番号と住所の項目名を示す
HOAI Point

legendはグループ名、labelは各コントロールの名前です。どちらか一方で代用せず、説明する範囲に合わせて併用しましょう。

fieldset・legend・label・divの違い

フォームでよく使う4つの要素は、説明する範囲と意味が異なります。

要素主な役割使う対象
fieldset関連するフォーム項目をグループ化する複数のコントロールとlabel
legendfieldset全体の見出しを示す親fieldsetのグループ名
label一つのフォーム部品の項目名を示すinput・select・textareaなど
div汎用的なコンテナーとして配置をまとめる意味を持たないレイアウト単位

fieldsetとdivの違い

divは汎用的なコンテナーです。CSSで枠線を付ければfieldsetに似た見た目にはできますが、「ここは関連するフォーム項目のグループである」という意味は持ちません。

fieldsetはフォーム項目の関係を表し、divは主に配置やスタイルのために使います。fieldsetの内側で、各行のレイアウト用にdivを併用しても構いません。

legendとlabelの違い

legendはグループ全体、labelは個別のコントロールを説明します。たとえば「希望する連絡方法」はlegend、「メール」「電話」はそれぞれのradioへ付けるlabelです。

idはページ内で部品を見分ける名前です。labelのforへ相手のidと同じ値を書くと、項目名と部品が関連付きます。たとえばfor="contact-email"はid="contact-email"の入力部品を指します。legendを追加しても、この関連付けは残します。

fieldsetを使う場面・使わない場面

fieldsetはフォーム内のすべての項目へ機械的に付けるタグではありません。判断の軸は、複数のコントロールに共有見出しが必要かどうかです。

状況fieldsetの判断理由
一つの質問に複数のradioがある使う質問全体と各選択肢を分けられる
複数のcheckboxを一つのテーマで選ぶ使う選択肢の共通目的を示せる
配送先・請求先などの入力欄セット使う同じ項目名をグループ名で区別できる
お名前だけの単独入力欄通常は使わないlabelだけで目的が伝わる
見た目の枠や余白だけが欲しい使わないdivとCSSで配置を整える

radio・checkboxの選択肢をまとめる

radioや複数のcheckboxでは、各選択肢のlabelだけを読んでも、何について選ぶのか分からない場合があります。fieldsetとlegendを使うと、共有する質問と個々の答えを分離できます。

住所や連絡先の入力欄をまとめる

郵便番号・都道府県・住所のように、複数の入力欄で一つの情報を完成させる場面にも使えます。配送先と請求先の両方があるフォームでは、legendが同じ項目名の区別に役立ちます。

単独項目と見た目だけの枠

複数項目に共有見出しがなければ、fieldsetを無理に追加する必要はありません。一つの入力欄はlabelで説明し、見た目だけをまとめたい場合はdivなどを使います。

HOAI Point

「この項目群を一言で呼ぶ必要があるか」を判断基準にすると、fieldsetの使いすぎと不足を防げます。

radioボタンをfieldsetでまとめる書き方

radioは、一つの質問から一つだけ選ぶフォーム部品です。fieldsetとlegendで質問全体を示し、各radioへlabelを付けます。

<fieldset>
  <legend>希望する連絡方法</legend>

  <div>
    <input
      type="radio"
      id="contact-email"
      name="contact_method"
      value="email"
    >
    <label for="contact-email">メール</label>
  </div>

  <div>
    <input
      type="radio"
      id="contact-phone"
      name="contact_method"
      value="phone"
    >
    <label for="contact-phone">電話</label>
  </div>
</fieldset>

質問全体と選択肢の書き分け

legendには「希望する連絡方法」のような質問を書きます。各labelには「メール」「電話」のような選択肢を書きます。

質問全体はlegend、選択肢ごとの名前はlabel、同じ質問のradioは共通のnameにします。idは各radioで一意にし、対応するlabelのforへ同じ値を書きます。

fieldsetとradioのnameの役割

fieldsetは項目の意味上のまとまりを表します。一方、同じフォームに属するradioのnameをそろえると、一つを選んだときに別の選択が外れます。fieldsetで囲むだけでは、この「一つだけ選ぶ」動作にはなりません。別の質問のradioには別のnameを付けます。

HOAI Point

意味のまとまりはfieldset、radioの選択グループは共通のnameが担当します。両方を正しく設定しましょう。

inputのtype・name・valueを整理したい方は、HTMLのinputタグとtype・name・valueの書き方も参考にしてください。

checkboxをfieldsetでまとめる書き方

複数の項目を選べるcheckboxでも、共通する質問がある場合はfieldsetとlegendを使います。

<fieldset>
  <legend>興味のある分野をすべて選んでください</legend>

  <div>
    <input type="checkbox" id="topic-html" name="topics" value="html">
    <label for="topic-html">HTML</label>
  </div>

  <div>
    <input type="checkbox" id="topic-css" name="topics" value="css">
    <label for="topic-css">CSS</label>
  </div>

  <div>
    <input type="checkbox" id="topic-js" name="topics" value="javascript">
    <label for="topic-js">JavaScript</label>
  </div>
</fieldset>

複数選択の条件の伝え方

「すべて選んでください」「複数選択可」のような条件があるなら、legendや直後の説明文へ簡潔に書きます。各checkboxのlabelは選択肢そのものを表します。

単独checkboxの書き方

利用規約への同意やメール配信の希望など、質問と選択肢が一つのlabelだけで明確な場合は、fieldsetを追加しなくても構いません。

<input type="checkbox" id="newsletter" name="newsletter" value="yes">
<label for="newsletter">お知らせメールを受け取る</label>

単独checkboxは、共有見出しが不要ならlabelだけで説明できます。

住所などのテキスト入力をまとめる書き方

fieldsetはradio・checkbox専用ではありません。配送先住所と請求先住所のように、同じ種類の入力欄が複数セットあるフォームでも役立ちます。

<fieldset>
  <legend>配送先住所</legend>

  <label for="shipping-postal-code">郵便番号</label>
  <input
    type="text"
    id="shipping-postal-code"
    name="shipping_postal_code"
  >

  <label for="shipping-address">住所</label>
  <input
    type="text"
    id="shipping-address"
    name="shipping_address"
  >
</fieldset>

<fieldset>
  <legend>請求先住所</legend>

  <label for="billing-postal-code">郵便番号</label>
  <input
    type="text"
    id="billing-postal-code"
    name="billing_postal_code"
  >

  <label for="billing-address">住所</label>
  <input
    type="text"
    id="billing-address"
    name="billing_address"
  >
</fieldset>

配送先と請求先の区別

どちらのグループにも「郵便番号」「住所」というlabelがあります。fieldsetごとの「配送先住所」「請求先住所」というlegendが加わることで、各入力欄の所属を区別できます。

同じ郵便番号と住所の入力欄を、配送先住所と請求先住所という二つのlegendで区別する

複数行の住所や補足を入力する場合は、HTMLのtextareaタグとrows・cols・placeholderの書き方も参考にしてください。フォーム全体の基本構造は、HTMLフォームとform・input・label・buttonの違いで解説しています。

fieldsetで使えるdisabled・name・form属性

fieldsetでは、グループ全体の無効化や識別に使う属性も指定できます。

属性主な役割初心者向けの注意点
disabled子孫のフォーム部品をまとめて無効にする操作できず、通常は送信されない
namefieldset自体へ名前を付けるradioの選択グループは作らない
formfieldsetを離れたformと関連付ける子孫コントロールへは継承されない

disabled属性でグループを無効にする

fieldsetへdisabled属性を付けると、その子孫のフォーム部品をまとめて無効にできます。ただし、最初のlegendの内側にあるフォーム部品は例外です。

<fieldset disabled>
  <legend>現在は変更できない設定</legend>

  <label for="plan">プラン</label>
  <select id="plan" name="plan">
    <option value="basic">ベーシック</option>
    <option value="pro">プロ</option>
  </select>
</fieldset>

無効になった入力欄は操作できず、Tabキーで選んで入力できる状態(フォーカス)にも移れません。フォーム送信時のデータにも含まれません。disabledは見た目だけでなく操作と送信結果にも影響します。

MDNのdisabled属性の解説で、無効なフォーム部品の挙動を確認できます。

試すときは、後半の練習コードの<fieldset>を<fieldset disabled>へ変更し、保存して再読み込みします。選択肢が操作できず、送信後のURLにcontact_methodが含まれなくなります。元へ戻すときはdisabledを属性ごと削除して再読み込みしてください。disabled="false"と書いても無効化は解除されません。

disabled付きfieldsetのプランは操作・送信できず、disabledを外すと操作できる。最初のlegend内の部品は例外
HOAI Point

値を見せたまま送信したい場面でdisabledを安易に使わないことが重要です。サーバーへ必要な値が届くか、実際の送信データまで確認しましょう。

fieldsetのname属性の役割

fieldsetのnameはfieldset自体を識別する属性です。同じ質問のradioを一つだけ選べる状態にするには、各radioへ同じnameを書きます。

form属性で関連付ける範囲

fieldsetをform要素の外へ置き、form="contact-form"で関連付けることはできます。ただし、その指定が内側のinputへ自動で引き継がれるわけではありません。離れたformへ各入力値を送る必要があるなら、子孫コントロールにもそれぞれform属性を指定します。

<form id="contact-form" action="/contact" method="post"></form>

<fieldset form="contact-form">
  <legend>連絡先</legend>

  <label for="email">メールアドレス</label>
  <input
    type="email"
    id="email"
    name="email"
    form="contact-form"
  >
</fieldset>

この例の/contactは仮の送信先です。HTMLの関連付けを示す部分コードで、メールを届ける仕組みは含みません。実際の送信には、サイト側で用意した送信先と受信処理が必要です。初めはfieldsetをformの内側へ置く基本形から試しましょう。

fieldset・legendをCSSで整える方法

fieldsetとlegendにはブラウザーの既定スタイルがあります。次のHTMLを練習ファイルのbody内へ置き、CSSをhead内の<style>…</style>に書くと、枠線や余白を調整できます。各部分コードは別々の例です。同じページへ組み合わせる場合は、idが重複しないよう変更してください。

<fieldset class="form-group">
  <legend class="form-group__title">配送先住所</legend>

  <div class="form-row">
    <label for="postal-code">郵便番号</label>
    <input type="text" id="postal-code" name="postal_code">
  </div>
  <div class="form-row">
    <label for="address">住所</label>
    <input type="text" id="address" name="address">
  </div>
</fieldset>
.form-group {
  margin: 0 0 24px;
  padding: 20px;
  border: 1px solid #c9d4d8;
  border-radius: 8px;
}

.form-group__title {
  padding: 0 8px;
  font-weight: 700;
}

.form-row {
  display: grid;
  gap: 8px;
  margin-block: 12px;
}

枠線だけを消す方法

border: 0で見た目の枠線を消しても、fieldsetとしてのHTML構造は残ります。デザイン上の枠が不要でも、意味上のグループが必要ならfieldsetを使えます。

legendを非表示にする場合の注意点

legendはグループの目的を画面上でも示します。単にデザインへ合わないという理由だけで非表示にせず、短い見出しへ直すか、スタイルを調整してください。視覚的に隠す必要が本当にある場合は、画面利用者と支援技術の両方で文脈が保たれるかを個別に検証します。

fieldset・legendの動作を試す練習コード

次のコードは、一つのHTMLファイルだけで選択と送信対象の値を確かめる例です。この記事のコード枠自体は入力画面ではありません。method="get"は、選んだ値をURLの?以降へ付ける送信方法です。手元のファイルとして開く練習では、メール送信やサーバー側の受信処理は行いません。

<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>fieldsetとlegendの練習</title>
</head>
<body>
  <h1>希望する連絡方法を選ぶ</h1>
  <p>選択した値をURLで確かめる練習です。</p>
  <form method="get">
    <fieldset>
      <legend>希望する連絡方法</legend>
      <p>
        <input type="radio" id="contact-email"
          name="contact_method" value="email">
        <label for="contact-email">メール</label>
      </p>
      <p>
        <input type="radio" id="contact-phone"
          name="contact_method" value="phone">
        <label for="contact-phone">電話</label>
      </p>
    </fieldset>
    <p><button type="submit">選んだ値を確認する</button></p>
  </form>
</body>
</html>
  1. HTMLファイルを保存して開く
    コード全体をテキストエディターへコピーし、文字コードUTF-8でfieldset-practice.htmlという名前で保存します。末尾が.html.txtになっていないことを確かめ、ファイルをブラウザーで開きます。「希望する連絡方法」の下に「メール」「電話」とボタンが表示されれば準備できています。
  2. 選択肢の文字で切り替える
    「メール」の文字をクリックしてから「電話」の文字をクリックします。丸い選択欄の印がメールから電話へ移り、同時に二つ選ばれなければ、labelと共通のnameが働いています。
  3. 選んだ値をURLで確認する
    「電話」を選んだ状態で「選んだ値を確認する」を押し、ブラウザーのアドレス欄に?contact_method=phoneが付くことを確認します。「メール」を選んで再度押すと?contact_method=emailに変わります。値が切り替われば練習は完了です。

何も選ばずに押した場合、radioの値はURLに付きません。各値の役割は、nameが項目名のcontact_method、valueが選択肢ごとのemail・phoneです。

fieldset・legendでよくある間違いと確認方法

すべての確認を順番に行う必要はありません。起きている症状に合う項目から直し、保存して再読み込みした後、期待する状態になれば確認を終えます。

  • グループ名がない・所属が分からない:fieldsetの先頭にlegendが一つあるか確認し、質問全体と各項目名を区別できる状態にします。
  • 項目名をクリックしても動かない:labelのforと部品のidを一致させ、idの重複をなくします。文字から対象部品を選べれば完了です。
  • radioを複数選べてしまう:同じフォーム内の同じ質問でnameをそろえます。別の選択肢を選んだとき、選択が一つに切り替われば完了です。
  • 入力できない・選んだ値が送られない:部品と親fieldsetのdisabledを確認します。送信先・name・未選択の有無も見直し、練習例ではURLの値で確かめます。
  • 枠が多くて分かりにくい:共有見出しが不要なfieldsetや深い入れ子を減らし、グループと項目の所属を追える状態にします。

よくある間違い1|legendを書かない・先頭に置かない

<!-- legendより前に入力欄がある -->
<fieldset>
  <input type="radio" id="size-s" name="size" value="s">
  <legend>サイズ</legend>
  <label for="size-s">S</label>
</fieldset>

legendをfieldsetの先頭へ移し、グループ名を最初に示します。

よくある間違い2|legendだけで各labelを省く

<!-- 各入力欄の意味を区別できない -->
<fieldset>
  <legend>配送先住所</legend>
  <input type="text" name="postal_code">
  <input type="text" name="address">
</fieldset>

legendは「配送先住所」というグループ名です。それぞれの入力欄へ「郵便番号」「住所」のlabelを付けます。

よくある間違い3|一項目ごとにfieldsetを使う

<!-- 共有する複数項目がない -->
<fieldset>
  <legend>お名前</legend>
  <input type="text" id="name" name="name">
</fieldset>

単独の入力欄なら、通常は<label for="name">お名前</label>で十分です。fieldsetを増やしすぎると、構造と読み上げがかえって複雑になります。

自動生成されたHTMLの確認方法

WordPressなどでフォームを自動生成する場合は、編集したひな形と実際に表示されるHTMLが異なることがあります。Chromeでは問題の入力欄を右クリックし、「検証」を開いて「要素(Elements)」を確認します。この表示に使われる要素の構造をDOMと呼びます。入力欄のidとlabelのfor、親fieldsetのdisabled、legendの位置を見比べ、元のHTMLや生成設定を直して再読み込みします。開発者ツール内だけの編集は、通常、元のファイルへ保存されません。

よくある質問

radioやcheckboxにはfieldsetが必須ですか?

HTMLの構文上、すべてのradio・checkboxで必須というわけではありません。ただし、複数の選択肢に一つの質問が共通する場合は、fieldsetとlegendで関係を示すのが適切です。単独checkboxはlabelだけで目的が明確ならfieldsetを省けます。

legendをCSSで非表示にしてもよいですか?

legendはグループ名を画面上と支援技術へ伝える役割があります。デザイン上の都合だけで非表示にせず、短い文言やスタイル調整を優先してください。非表示が必要な場合は、視覚的な文脈とアクセシブルな名前が失われないか検証します。

fieldsetを入れ子にできますか?

はい、構文上は入れ子にできます。大きな質問の中に明確な下位グループがある場合に使えますが、深い入れ子は理解しにくくなるため、必要最小限にします。

一つのfieldsetにlegendを複数書けますか?

いいえ。正しいHTMLでは、一つのfieldsetに置くlegendは一つまでで、最初の子要素にします。グループ名は一つにまとめ、補足はlegendの後の段落へ書きます。最初のlegendが見出しとして使われても、複数置いた書き方が適切になるわけではありません。

fieldsetの代わりにdivを使えますか?

見た目の配置だけならdivとCSSを使えます。しかし、関連するフォーム項目であることをHTML上に表したい場面では、divだけではfieldsetとlegendの意味を代用できません。

legendの中に入力欄を置けますか?

はい、inputなどを置けます。最初のlegend内の部品は、親fieldsetにdisabledを付けても、その属性による無効化の対象から外れます。ただし、legend内のチェックボックスを押すだけでグループ全体が自動で有効になるわけではありません。その切り替えにはJavaScriptなどの処理が必要です。通常は簡潔なグループ名を基本にします。

まとめ

fieldset・legendタグは、関連するフォーム項目と共有見出しの関係をHTMLへ表すための要素です。

  • 共有する質問や見出しがある複数項目をfieldsetで囲む
  • legendをfieldset直下の最初の子要素にする
  • legendはグループ名、labelは各フォーム部品の名前として併用する
  • radioの選択グループには各radioで共通のnameも設定する
  • 単独項目や見た目だけの枠にはfieldsetを無理に使わない
  • disabledは操作だけでなく送信データにも影響する
  • 動かないときは、症状に合う確認先を選び、修正後の表示と選択状態を確かめる

まずは練習コードを保存して開き、「メール」「電話」の文字から一つだけ選べることと、URLに選択した値が付くことを確かめましょう。そこまでできれば、fieldset・legend・label・nameの役割を一つの例で確認できています。

目的別に次の記事を選ぶ

グループを作れたら、個々の項目名と入力部品の関連付けも確かめましょう。

項目名をクリックしても入力欄へ移れない場合は、labelのfor・idの対応を確認すると原因を絞れます。

HTMLのlabelタグ|for・idの関連付けと書き方を確認する

この記事を書いた人

横畑デザイン事務所代表。Webデザイナー・プログラミング講師として、WordPressを中心としたWebサイトの制作・運用と個別指導に携わっています。実際の制作や指導で培った知識と経験をもとに、Web制作やAI活用について、初心者が迷わず一歩を踏み出せる情報を分かりやすく発信しています。

目次