You will style a form as a responsive grid container and use fieldsets and legends to group related controls with clear visual and accessible structure.
What it is
A form container is the outer element that arranges fields, groups, and buttons. In CSS, the form element is often the layout root. A fieldset is a semantic container for a group of related controls, such as address fields or radio choices. The legend element names that group. Related terms include label, input, button, and gap.
The mental model is: form controls overall spacing and width, fieldset creates a visual and semantic box, and legend sits on the box edge to explain the group.
Why it matters
- It gives users a predictable reading order and consistent spacing.
- It makes grouped controls easier to scan, especially for checkboxes and radio buttons.
- It supports accessibility because assistive technology can announce the group name from the legend.
- It lets you build responsive forms with simple grid rules instead of fragile margins.
- It separates layout from decoration, so you can change width, borders, and focus styles independently.
Syntax or steps
- Make the form a grid container with
display: grid,gap, andmax-width. - Wrap related controls in
fieldsetand give each group alegend. - Reset the default fieldset spacing with
margin: 0andpadding. - Use an inner container, such as
div.fields, for reliable grid layout inside the fieldset. - Style labels, inputs, and buttons with inherited font and consistent padding.
form { display: grid; gap: 12px; max-width: 400px; }
fieldset { margin: 0; padding: 12px; border: 1px solid #ccc; }
legend { padding: 0 4px; }
Example
<style>
form {
display: grid;
gap: 16px;
max-width: 420px;
margin: 0 auto;
}
fieldset {
margin: 0;
padding: 16px;
border: 1px solid #cbd5e1;
border-radius: 8px;
}
legend {
padding: 0 6px;
font-weight: 600;
}
.fields {
display: grid;
gap: 8px;
}
label {
font-size: 0.95rem;
}
input,
button {
font: inherit;
}
input[type="email"],
input[type="password"] {
padding: 8px 10px;
border: 1px solid #94a3b8;
border-radius: 6px;
}
button {
padding: 10px 14px;
border: 0;
border-radius: 6px;
background: #2563eb;
color: white;
cursor: pointer;
}
</style>
<form>
<fieldset>
<legend>Account</legend>
<div class="fields">
<label for="email">Email</label>
<input id="email" type="email" required>
<label for="password">Password</label>
<input id="password" type="password" required>
</div>
</fieldset>
<fieldset>
<legend>Preferences</legend>
<div class="fields">
<label><input type="checkbox" name="newsletter"> Send updates</label>
</div>
</fieldset>
<button type="submit">Create account</button>
</form>
Part by part:
formcreates the outer grid and limits width so the form does not stretch too far on large screens.fieldsetdraws a bordered group and resets default margin so spacing comes from the form grid.legendlabels the group and receives small padding so it sits cleanly over the border..fieldsis an inner grid that stacks labels and controls with consistentgap.font: inheritmakes controls match the page typography instead of using browser defaults.
Common mistakes
- Using a plain div for a semantic group. If controls belong together, use
fieldsetandlegend, or usediv role="group" aria-labelledby="id"when fieldset styling is problematic. - Forgetting the legend. A fieldset without a legend gives no accessible group name.
- Applying grid directly to fieldset without testing. Fieldsets have special rendering; an inner
divis often more reliable. - Leaving default margins and borders. Reset
margin,padding, andborderonfieldsetso your spacing system stays predictable.
When to use it
Use fieldset when the group has semantic meaning. Use a styled div when the grouping is only visual or when you need a layout pattern that fieldsets handle poorly.
| Pattern | Best for | Watch out for |
|---|---|---|
form grid + fieldset | Accessible grouped forms, radio sets, checkbox sets, multi-section forms | Default fieldset borders and legend placement |
form grid + div | Simple visual sections or custom layout containers | Missing semantic group name unless ARIA is added |
form flex column | Very simple one-column forms | Less control over two-column or complex spacing |
Practice
Guided exercise: create a form with two fieldsets, one for “Contact” and one for “Availability.” Style the form with display: grid, gap: 16px, and max-width: 400px. Put labels and inputs inside a div.fields grid.
Expected output: the two fieldsets stack vertically with equal spacing, each has a visible border, and the legend appears at the top of its group.
Challenge: add a focus style such as input:focus-visible { outline: 2px solid #2563eb; outline-offset: 2px; }. Hint: test with the keyboard Tab key.
Quick check
Question: Which element provides the accessible name for a fieldset?
Answer: The legend element.
Summary
Styling forms is easier when you separate layout from grouping: the form arranges the whole page section, while fieldset and legend create meaningful groups. A grid container with consistent gap gives forms a clean, responsive structure without fragile margins.