ESC

Type to search the knowledge base.

Accent Color and Form Controls

Use accent-color to theme native checkboxes, radios, ranges, and progress — what it paints, what it skips, and when to custom-style instead.

beginner3 min read
  • css
  • accent-color
  • forms

Native form controls used to fight your brand: blue checkboxes on one OS, grey ranges on another. accent-color is the smallest lever that recolors the browser’s accent chrome on supported controls without rebuilding the whole widget.

Docs: MDN accent-color, CSS UI Module.

What it actually paints

:root {
  accent-color: #0b6bcb;
}

/* Or scope it */
.form-branded {
  accent-color: var(--brand);
}

Typical hits (browser-dependent, but this is the mental model):

Control Effect of accent-color
input[type="checkbox"] Checked fill / mark chrome
input[type="radio"] Selected disc
input[type="range"] Thumb and/or track accent
progress Filled portion
Some input[type="checkbox"] switches Platform-dependent

It does not restyle text fields, select menus, file pickers, or every pixel of a control. Borders, focus rings, and label text stay under your normal CSS (or the UA stylesheet).

<label>
  <input type="checkbox" name="terms" />
  Accept terms
</label>
<input type="range" min="0" max="100" value="40" />
<progress max="100" value="60">60%</progress>

One declaration on a parent is often enough — accent-color inherits.

Mental model

Think brand tint for native affordances, not a design-system replacement. You keep:

  • Platform rendering and hit targets
  • Built-in keyboard and AT behavior
  • Less JS than a fully custom checkbox

You give up pixel-perfect parity across Safari/Chrome/Firefox and OS themes. That’s usually fine for product UIs that already accept platform variance.

Pairing with real form CSS

.field {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  accent-color: var(--brand-600);
}

.field input[type="checkbox"] {
  width: 1.125rem;
  height: 1.125rem;
}

.field:focus-within {
  /* Don’t rely on accent-color for focus — style :focus-visible on the control */
}

Focus is separate. Use :focus-visible outlines (or a design token ring). accent-color is not a focus indicator and must not replace one.

Contrast matters: a pale accent on a white page can fail WCAG for non-text UI components. Check the filled state against adjacent backgrounds.

When not to stop at accent-color

Build custom controls (with care) when you need:

  • Animated checkmarks, indeterminate art, or multi-state chips
  • Identical rendering in design QA across OSes
  • Complex switch labels that the native control can’t express

Custom means you own keyboard, aria-checked, hit area (≥24×24 CSS px guidance), and high-contrast mode. For a settings form, native + accent-color usually wins.

/* Optional: only when the engine supports it */
@supports (accent-color: red) {
  form {
    accent-color: var(--brand);
  }
}

Unsupported engines ignore the property; controls stay UA-colored. That’s progressive enhancement, not a bug.

Color-scheme interaction

:root {
  color-scheme: light dark;
  accent-color: light-dark(#0b6bcb, #6cb6ff);
}

Dark mode can wash out a light-only brand blue. Prefer a token that adapts, or set accent-color under prefers-color-scheme / a .theme-dark class.

Interview out-loud

“accent-color sets the accent used by some native form controls — checkboxes, radios, ranges, progress. It inherits, so one rule on the form is enough. It doesn’t restyle text inputs or replace focus styles. I’d use it for light branding of native widgets; for full visual control I’d build accessible custom controls and accept the extra a11y work.”

Footguns

  1. Assuming every control and every browser matches your Figma file.
  2. Using a low-contrast brand color and calling it “done.”
  3. Removing outlines because “the accent looks focused.”
  4. Fighting appearance / vendor pseudo-elements and accent-color without a clear fallback path.
  5. Forgetting forced-colors / Windows High Contrast — custom paints break more often than native.

Further reading

Related guides