Skip to content
AgileLogics
6 min read

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% plus box-sizing: border-box makes them fill their container exactly.
  • Keep borders visible with enough contrast (3:1 against the background) — borderless inputs are hard to find.
  • :user-invalid marks 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;
}