CSS accent-color - Stop Shipping Grey Checkboxes
Change the color of checkboxes, radio buttons, and range sliders with one line of CSS.
No custom components. No JavaScript. No "just rebuild the entire input from divs". Native controls that finally look intentional.
Controls
Live demo: Native form controls
Before vs After
💡 Browser support: Chrome 93+, Firefox 92+, Safari 15.4+. Supported in all modern browsers since 2021.
What is accent-color?
The accent-color CSS property lets you change the highlight color of native form controls:
- Checkboxes
- Radio buttons
- Range sliders (
<input type="range">) - Progress bars (
<progress>)
One property. All of these elements. No custom styling layers.
input[type="checkbox"], input[type="radio"], input[type="range"], progress { accent-color: #22c55e; }
That is it. Your form controls now match your brand instead of looking like default OS grey.
Why this matters
Before accent-color, if you wanted branded form controls, you had three bad options:
- Ship default grey controls - looks unpolished and off-brand
- Use a library - add 15kb of JavaScript for a checkbox
- Build custom components - spend two days styling a checkbox, break keyboard navigation, forget about screen readers
All of these are worse than one line of CSS.
Basic usage
Apply globally
Set it once in your root or body:
:root { accent-color: #3b82f6; /* your brand color */ }
Every checkbox, radio, slider, and progress bar on your site now uses that color.
Scope to specific forms
Or apply it only to certain areas:
.signup-form { accent-color: #22c55e; } .danger-zone { accent-color: #ef4444; }
Forms can have different accent colors based on context.
Per-element control
You can also set it on individual inputs:
input[type="checkbox"].primary { accent-color: var(--primary); } input[type="checkbox"].danger { accent-color: var(--danger); }
Though at this point you may be optimising your checkboxes more than your actual product.
Combine with color-scheme
For maximum effect, pair accent-color with color-scheme:
:root { color-scheme: dark light; /* respect the user's OS preference */ accent-color: #22c55e; /* your brand color */ }
Now:
- Native controls (form inputs, scrollbars) align with dark/light mode
- Your brand color shows up without fighting the OS theme
- Zero JavaScript - the browser handles the mode switch
For most sites, this two-line setup is enough.
When NOT to use accent-color
accent-color is great for basic form branding, but it is not a magic bullet.
Skip it if:
- You need complex custom styling (gradients, shadows, animations)
- You are building a design system with very specific control visuals
- You need to support browsers from before ~2021
- You are intentionally replacing the native control entirely (e.g. fancy toggle switches)
Use it for:
- Standard forms that should simply match your brand
- Prototypes and MVPs where custom controls are overkill
- Accessible forms where you want to keep native behaviour
- Any situation where "good enough, fast" beats "pixel-perfect, maybe later"
If your form just needs to stop looking like Windows 95, accent-color is your friend.
Real-world examples
Signup form
.signup-form { accent-color: #22c55e; }
<form class="signup-form"> <label> <input type="checkbox" /> I agree to the terms </label> <label> <input type="checkbox" /> Send me product updates </label> </form>
Your checkboxes now match your brand. No library. No custom components.
Settings panel with sections
.settings-section--danger { accent-color: #ef4444; } .settings-section--success { accent-color: #22c55e; }
<div class="settings-section--danger"> <label> <input type="checkbox" /> Delete my account </label> </div> <div class="settings-section--success"> <label> <input type="checkbox" checked /> Two-factor authentication enabled </label> </div>
Different sections get different accent colors. Still just CSS.
Range slider for volume control
.volume-control { accent-color: #3b82f6; }
<div class="volume-control"> <label>Volume</label> <input type="range" min="0" max="100" value="70" /> </div>
The slider track and thumb now match your UI instead of whatever your browser felt like.
Accessibility
Because accent-color works with native controls, it inherits their accessibility:
- ✅ Keyboard navigation works
- ✅ Screen readers announce correctly
- ✅ Focus states are preserved
- ✅ ARIA attributes behave as expected
The browser handles all of this. You just change the color.
Contrast considerations
Make sure your accent color has enough contrast:
- Checked vs unchecked states must be visually distinct
- Focus indicators should remain visible
- Text labels should meet WCAG contrast ratios (4.5:1 for normal text)
Most brand colors are fine. If yours is very light or very dark, test with real controls, not just a color swatch.
Browser support
accent-color is supported in all modern engines:
- Chrome 93+
- Firefox 92+
- Safari 15.4+
- Edge 93+
This covers the vast majority of users.
Fallback
Older browsers simply ignore accent-color and fall back to the default OS color. Your forms still work - they just look less branded.
That is classic progressive enhancement: new browsers get the nice touches, old ones get the basics.
Performance
accent-color is a native CSS property. There is essentially no performance cost.
Compare this to:
- Custom checkbox libraries - JavaScript, event listeners, state management
- SVG-based controls - extra DOM nodes and rendering work
- Custom-styled inputs -
appearance: noneplus reimplementing every state by hand
accent-color is free. Use it until you actually have a concrete reason not to.
Common patterns
⚖️ Council advice: When not to introduce a design token for every accent-color variant
You do not need --accent-primary, --accent-secondary, --accent-tertiary, --accent-quaternary, and seventeen other variants. Most apps need exactly one global accent color. If you are building a design system for a company with multiple sub-brands, fine - add two or three. But if you are adding accent tokens "just in case" or because it feels architecturally complete, you are solving a problem you do not have. One color. One token. Move on.
Match your design system
:root { --color-primary: #3b82f6; --color-success: #22c55e; --color-danger: #ef4444; } /* Default: primary brand color */ input[type="checkbox"], input[type="radio"], input[type="range"], progress { accent-color: var(--color-primary); } /* Success context */ .success-message input { accent-color: var(--color-success); } /* Danger context */ .danger-zone input { accent-color: var(--color-danger); }
Your form controls now respect your design tokens instead of hard-coded hex values.
Dark mode aware
:root { color-scheme: dark light; } @media (prefers-color-scheme: light) { :root { accent-color: #2563eb; /* slightly darker for light mode */ } } @media (prefers-color-scheme: dark) { :root { accent-color: #60a5fa; /* slightly lighter for dark mode */ } }
Your accent color adapts to the user's theme preference. Still no JavaScript.
Component-scoped
/* In your CSS module or scoped styles */ .card { accent-color: var(--card-accent); }
Each component can have its own accent color if needed. Most of the time, a single global value is enough.
Try it yourself
The demo above shows accent-color in action. Toggle it, change colors, and watch native controls follow along.
Then copy this into your project:
:root { color-scheme: dark light; accent-color: #22c55e; /* your brand color */ }
One declaration. Every form on your site suddenly looks like somebody cared.
Resources
- MDN: accent-color - official documentation
- Can I Use: accent-color - browser support table
- web.dev: accent-color - guide from the Chrome team
Copy. Paste. Ship. Your forms no longer have to cosplay as Windows 98.