Styling Forms
Form controls come with browser-specific default styles that are notoriously awkward to customise. Modern CSS makes it much easier: accent-color for quick theming, appearance: none for full control, and pseudo-classes for every state — without sacrificing accessibility.
A consistent base
Start by making controls inherit the page font (font: inherit) — they don't by default — and give them consistent padding, borders and a clear focus style.
accent-color: quick theming
One property recolours checkboxes, radio buttons, range sliders and progress bars, keeping all their native behaviour and accessibility.
Custom checkboxes with appearance: none
appearance: none removes the native look so you can draw your own, while the element remains a real checkbox: it still works with the keyboard, labels and screen readers. Always restyle the real input rather than hiding it behind a fake one.
Toggle switches
role="switch" tells screen readers to announce it as on/off rather than checked/unchecked.
Styling selects and file inputs
A select with appearance: none needs its own arrow (an SVG background here). ::file-selector-button styles the button inside a file input. Newer browsers also support fully customisable select menus with appearance: base-select.
Validation states
:user-invalid only matches after the user has interacted with a field, and :has() lets the field's wrapper reveal an error message — no JavaScript needed for the basics.
Placeholders and autofill
::placeholder {
color: #8a91a5;
opacity: 1;
}
input:autofill {
box-shadow: inset 0 0 0 100px #eef4fc;
}
textarea {
field-sizing: content;
min-height: 3lh;
resize: vertical;
}
Firefox lowers placeholder opacity by default, so set opacity: 1 for consistency. :autofill styles fields filled in by the browser. field-sizing: content makes a textarea grow with its text.
Keep forms accessible
- Never remove focus indicators.
- Keep borders with enough contrast (3:1) so fields are recognisable.
- Make click targets large — style the label, not just the tiny input.
- Don't rely on colour alone for errors; add a message.