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.
Content Table
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
legendtext 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. Thelegendnames the group; individuallabels name each option. Both are needed. -
All three inputs share the same
nameattribute, 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 |
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>
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
legendmust be the first child offieldset. 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
fieldsetjust for the border effect, use adivwith CSS instead. Overusingfieldsetoutside 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
fieldsetelements 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
legendnames the group. It does not replacelabelelements 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.
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.