How to align form labels and fields
Short answer
The simplest is labels above the fields: each pair stacked in a column with a small gap:
<style>
form { display: grid; gap: 12px; max-width: 280px; }
label { display: grid; gap: 4px; }
</style>
<form>
<label>Name <input name="name"></label>
<label>Email <input name="email" type="email"></label>
</form>A field inside <label> is linked to the label: a click on the text puts the cursor in the field, and a screen reader reads the label as its name.
Labels on the left
For labels on the left a two-column grid works well: the labels take the width of the longest one, the fields take the rest:
<style>
form { display: grid; grid-template-columns: auto 1fr; gap: 8px 12px; align-items: center; max-width: 340px; }
</style>
<form>
<label for="name">Name</label> <input id="name">
<label for="city">Delivery city</label> <input id="city">
</form>Here the label and the field are siblings, so they are linked with the for and id attributes.
A checkbox and its text
A checkbox and its label are centered with flexbox:
<label style="display: flex; align-items: center; gap: 8px;">
<input type="checkbox"> Remember me
</label>On narrow screens, labels on the left are better moved to the top — a media query changes grid-template-columns to one column.
Common mistake
Labels are aligned with spaces or each gets a fixed width in pixels. Once the form is translated or the font is enlarged, a long label wraps and breaks the row. An auto column in the grid adjusts to the longest label by itself.
Functions used in this recipe
- <label> — A label for a form field.
- grid-template-columns — The number and widths of the columns of a grid.
- <form> — A form: collects data from its fields and sends it to the server.
- gap — The gaps between items in flexbox and grid.
- align-items — Aligns items across the main axis — vertically in a row.