Fieldset and Legend: Building Accessible Form Groups

Illustration of organized form elements and grouped input fields with glowing connections, representing accessible fieldset and legend structure in web design.

The fieldset and legend elements in HTML are the proper way to group related form controls together and label that group for both users and assistive technologies. Instead of wrapping radio buttons or checkboxes in a generic div , you wrap them in a fieldset and give the group a descriptive legend , so screen readers can announce the group's purpose before reading each individual input.

What fieldset and legend actually do

At the HTML level, fieldset creates a grouping container for form controls. The legend element, placed as the very first child of fieldset , provides the accessible name for that group. This is not just a visual label. It is wired directly into the browser's accessibility tree.

When a screen reader like NVDA or VoiceOver reaches a radio button inside a fieldset , it typically reads something like: "Preferred contact method, group. Email, radio button, 1 of 3." Without the fieldset and legend , the user just hears "Email, radio button" with no context about what they are actually choosing.

This is part of what the WCAG 2.1 criterion 1.3.1 (Info and Relationships) requires: relationships conveyed visually must also be available programmatically. A fieldset with a legend is one of the cleanest ways to satisfy that for form groups.

Basic syntax and structure

The structure is straightforward. The legend must be the first child of fieldset , and every related input goes inside the fieldset after it.

<fieldset>
  <legend>Preferred contact method</legend>

  <label>
    <input name="contact" type="radio" value="email"/> Email
  </label>

  <label>
    <input name="contact" type="radio" value="phone"/> Phone
  </label>

  <label>
    <input name="contact" type="radio" value="post"/> Post
  </label>
</fieldset>

A few things to notice here:

  • The legend text is short and descriptive. It tells users what the group is about , not just what to do.
  • Each radio button still has its own label . The legend names the group; individual label s name each option. Both are needed.
  • All three inputs share the same name attribute, which is how browsers know they are mutually exclusive.

When to use fieldset (and when to skip it)

Not every form needs a fieldset . The element has a specific purpose: grouping controls that share a common context. Here is a practical breakdown:

Situation Use fieldset? Reason
Radio button group (pick one) Yes, always Screen readers need group context to make individual options meaningful
Checkbox group (pick many) Yes, always Same reason as radio buttons; options only make sense as a set
Address fields (street, city, zip) Recommended Groups semantically related fields under a single "Shipping address" label
Single text input with its own label No A single label already provides the accessible name; fieldset adds no value
Simple contact form (name, email, message) Optional Each field has its own label; a fieldset could wrap the whole form but is not required
The golden rule : if removing the group label would make an individual option confusing or ambiguous, use a fieldset and legend .

The accessibility impact in practice

The MDN documentation on fieldset notes that the element has a native ARIA role of group , and the legend provides its accessible name automatically. This means you get correct screen reader behavior without writing a single line of ARIA.

Compare that to the common workaround of using a div with a heading:

<!-- Avoid: visually grouped but not semantically grouped -->
<div>
  <h3>Preferred contact method</h3>
  <label><input name="contact" type="radio" value="email"/> Email</label>
  <label><input name="contact" type="radio" value="phone"/> Phone</label>
</div>

<!-- Correct: semantically grouped -->
<fieldset>
  <legend>Preferred contact method</legend>
  <label><input name="contact" type="radio" value="email"/> Email</label>
  <label><input name="contact" type="radio" value="phone"/> Phone</label>
</fieldset>

The div version looks identical on screen but is invisible to assistive technology as a group. Screen reader users navigating by form controls will hear individual radio options with no announcement of what they belong to.

This also matters for keyboard navigation. When focus moves into a fieldset , some screen readers announce the legend text immediately, giving context before the user starts interacting with options.

Styling fieldset and legend without breaking semantics

Browsers apply default styles to fieldset (a border and some padding) and legend (bold text, positioned over the border). These defaults are often not what you want in a modern design, and resetting them is perfectly fine as long as you keep the elements in the DOM.

fieldset {
  border: none;
  padding: 0;
  margin: 0;
}

legend {
  font-weight: 600;
  font-size: 0.95rem;
  margin-bottom: 0.5rem;
  padding: 0;
}

One common pattern is visually hiding the legend while keeping it accessible. This is useful when the group's purpose is obvious from visual context but still needs to be announced to screen readers:

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

<fieldset>
  <legend class="visually-hidden">Newsletter preferences</legend>
  ...
</fieldset>
Never use display: none or visibility: hidden on a legend you want screen readers to announce. Those properties remove the element from the accessibility tree entirely.

Common mistakes to avoid

  • Putting legend anywhere other than first. The legend must be the first child of fieldset . Placing it elsewhere produces unpredictable rendering and breaks the accessible name computation.
  • Using fieldset for visual grouping only. If you are wrapping a section of a page in fieldset just for the border effect, use a div with CSS instead. Overusing fieldset outside form contexts adds noise to the accessibility tree.
  • Writing a vague legend. "Options" or "Choose" tells users nothing. Write the legend as if the user cannot see anything else on the page: "Notification frequency", "Billing address", "Payment method".
  • Nesting fieldsets without a clear hierarchy. Nested fieldset elements are valid HTML but can confuse screen reader users if the hierarchy is not logical. Only nest when the inner group is genuinely a sub-group of the outer one.
  • Skipping individual labels. The legend names the group. It does not replace label elements for individual inputs. Both are required.

A real-world contact form example

Here is a realistic contact form that uses fieldset correctly for a radio group and keeps individual fields properly labeled:

<form action="https://sendform.net/en/!a8Kz3mXq12" method="POST">

  <label for="email">Your email</label>
  <input id="email" name="email" required="" type="email"/>

  <label for="message">Message</label>
  <textarea id="message" name="message" required="" rows="5"></textarea>

  <fieldset>
    <legend>Preferred reply method</legend>

    <label>
      <input checked="" name="reply_method" type="radio" value="email"/> Email
    </label>

    <label>
      <input name="reply_method" type="radio" value="phone"/> Phone
    </label>
  </fieldset>

  <button type="submit">Send message</button>

</form>

Notice that the email and message fields stand on their own with individual label s, while the radio buttons are wrapped in a fieldset because they only make sense as a group. This is exactly the pattern you should follow in any semantic HTML form.

If you want to understand how the action attribute on that form actually works, the article on what the HTML form action attribute does covers the mechanics in detail. And if you are concerned about what happens to the data after submission, securing form submissions against CSRF and injection attacks is worth reading before you go live.

HTML form endpoint tool for accessible forms

Put your accessible fieldset form to work instantly

Once you have built a proper fieldset and legend form structure, you need somewhere to send the submissions. Sendform.net gives you a ready-made form endpoint URL, so your semantic HTML form starts delivering messages to your inbox without any server code.

Create a free form endpoint →

No, but those are the most common use cases. You can also use fieldset to group address fields (street, city, postal code), payment details, or any set of inputs that share a single logical purpose. The key question is whether a user would be confused by an individual field without knowing what group it belongs to. If yes, use a fieldset with a descriptive legend .

Technically yes. You can use role="group" with aria-labelledby on a div to replicate the effect. However, the first rule of ARIA is to use native HTML elements when they exist. The fieldset and legend combination is natively supported across all browsers and screen readers, requires no extra attributes, and is less likely to break. ARIA alternatives are a fallback for situations where you cannot change the markup, not a preferred approach.

No. The fieldset element is purely structural and semantic. It has no effect on which fields are submitted or how their values are serialized. The only exception is the disabled attribute: adding disabled to a fieldset disables all form controls inside it and excludes their values from submission. This is actually a useful technique for conditionally disabling a whole group of inputs at once.

Write it as if the user cannot see anything else on the page. It should describe what the group of controls is asking or representing, not just instruct the user to "select one". Good examples: "Notification frequency", "Shipping address", "Preferred payment method". Bad examples: "Options", "Select", "Choose below". Keep it concise, typically under eight words, and avoid punctuation at the end unless it is a question.

Yes, nested fieldset elements are valid HTML. A practical example is a billing section (outer fieldset ) that contains an address sub-group and a payment method sub-group (inner fieldset elements). Each needs its own legend . Screen readers will announce both the outer and inner group names as focus moves through the controls. Keep the hierarchy logical and limit nesting depth to two levels to avoid confusing users.

The default border is a visual hint that the enclosed controls form a group, matching the semantic meaning of the element. It comes from the browser's built-in user-agent stylesheet. You can remove or replace it with any CSS you like using border: none or a custom border style. The visual presentation has no effect on accessibility, so feel free to style it to match your design system while keeping the element in the DOM.