Styling Forms
Prerequisites: Styling links and interactive states
Form controls come with browser and operating-system styles. A few rules make them consistent and pleasant.
label {
display: block;
font-weight: 600;
margin-block-end: 0.25rem;
}
input,
select,
textarea,
button {
font: inherit;
}
input:not([type="checkbox"], [type="radio"]),
select,
textarea {
display: block;
width: 100%;
padding: 0.5rem 0.75rem;
border: 1px solid #8a8a8a;
border-radius: 6px;
background: white;
}
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
outline: 3px solid hsl(210 90% 60%);
outline-offset: 1px;
border-color: hsl(210 90% 40%);
}
textarea {
min-height: 6rem;
resize: vertical;
}
input:user-invalid {
border-color: #c62828;
}
::placeholder {
color: #6b6b6b;
}
font: inherit— form controls don't inherit fonts by default, so they'd otherwise look smaller and use a different font.- Inputs have an intrinsic width;
width: 100%plusbox-sizing: border-boxmakes them fill their container exactly. - Keep borders visible with enough contrast (3:1 against the background) — borderless inputs are hard to find.
:user-invalidmarks invalid fields only after the user has interacted with them (Chrome and Edge 119, Firefox 88, Safari 16.5).
accent-color
Checkboxes, radio buttons, range sliders, and progress bars take your brand color with one line:
:root { accent-color: hsl(160 70% 35%); }
Custom looks with appearance
appearance: none removes the native styling so you can draw your own —
for example a custom select arrow or a toggle switch. You then have to
style every state yourself, including focus, checked, and disabled.
Resizing form fields to content
field-sizing: content makes inputs and text areas grow with their
content. It's newer — supported in Chromium since 2024 and only
recently in Firefox and Safari — so treat it as an enhancement.
Practice
Style a checkbox label so the box and text line up with a small gap, and use the site's accent color.
Show solution
.check {
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.check input {
accent-color: hsl(160 70% 35%);
width: 1.1rem;
height: 1.1rem;
}