CSS
radio button
web design
styling forms
user interface

Change the circle color of radio button

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Changing the colored dot inside a radio button is easy in modern browsers and still possible in older ones with a custom control. The main decision is whether you can rely on accent-color or whether you need to remove the native appearance and draw the circle yourself.

Core Sections

The simplest modern solution: accent-color

If you only need to change the selected indicator color and can target modern browsers, accent-color is the cleanest option. It keeps the native radio button behavior, accessibility, and keyboard handling intact.

html
1<form class="preferences">
2  <label>
3    <input type="radio" name="theme" value="light" checked>
4    Light
5  </label>
6  <label>
7    <input type="radio" name="theme" value="dark">
8    Dark
9  </label>
10</form>
css
.preferences input[type="radio"] {
  accent-color: #0f766e;
}

That changes the selected circle color in supported browsers without rebuilding the control from scratch. Use this first unless you have strong branding or legacy-browser constraints.

Building a fully custom radio button

If you need total visual control, hide the browser appearance and recreate the indicator with CSS. The label remains clickable, so usability stays good if the markup is structured correctly.

html
1<label class="radio-option">
2  <input type="radio" name="plan" value="starter" checked>
3  <span class="radio-ui" aria-hidden="true"></span>
4  Starter
5</label>
6
7<label class="radio-option">
8  <input type="radio" name="plan" value="pro">
9  <span class="radio-ui" aria-hidden="true"></span>
10  Pro
11</label>
css
1.radio-option {
2  display: flex;
3  align-items: center;
4  gap: 0.6rem;
5  cursor: pointer;
6  font: 16px/1.4 sans-serif;
7}
8
9.radio-option input[type="radio"] {
10  position: absolute;
11  opacity: 0;
12  pointer-events: none;
13}
14
15.radio-ui {
16  width: 18px;
17  height: 18px;
18  border: 2px solid #475569;
19  border-radius: 50%;
20  display: inline-grid;
21  place-items: center;
22}
23
24.radio-ui::after {
25  content: "";
26  width: 10px;
27  height: 10px;
28  border-radius: 50%;
29  background: #0f766e;
30  transform: scale(0);
31  transition: transform 120ms ease-in-out;
32}
33
34.radio-option input[type="radio"]:checked + .radio-ui::after {
35  transform: scale(1);
36}
37
38.radio-option input[type="radio"]:focus-visible + .radio-ui {
39  outline: 3px solid #99f6e4;
40  outline-offset: 2px;
41}

In that pattern, the inner circle color is controlled by the background on .radio-ui::after.

What part actually changes the circle color

Native radios have two visual parts: the outer ring and the inner filled dot shown when selected. With accent-color, the browser handles both. With a custom radio, you usually style them separately:

  • outer ring: border
  • inner circle: pseudo-element background
  • checked state: selector based on :checked

If you only want the selected dot to be blue while keeping a gray outer ring, set a neutral border on the custom wrapper and apply the brand color only to the pseudo-element.

Accessibility requirements you should keep

Custom radios are easy to style badly. The control still needs:

  • a text label
  • visible focus styling
  • a large click target
  • grouped behavior through the same name

Do not replace the input with a div and JavaScript unless you are ready to reimplement keyboard navigation and semantics. A hidden real input plus styled companion element is the safer approach.

When JavaScript is not needed

Most radio-button color changes do not require JavaScript. CSS handles checked state, focus state, and transitions. JavaScript only becomes relevant if you are also syncing the selected value into a more complex visual component.

Common Pitfalls

  • Removing the native input entirely and losing keyboard and screen-reader behavior.
  • Using display: none on the radio input, which can make it non-focusable and harder to access correctly.
  • Forgetting a visible focus style after overriding native appearance.
  • Styling only the checked state and leaving the unchecked ring invisible on some backgrounds.
  • Using a custom solution when accent-color would have been simpler and more robust.

Summary

  • 'accent-color is the easiest way to change a radio button's selected color in modern browsers.'
  • For full visual control, hide the default appearance and draw the ring and dot with CSS.
  • Keep the real radio input in the DOM so labeling and keyboard behavior still work.
  • Separate the outer ring style from the inner selected dot style for precise control.
  • Prefer CSS-only solutions unless the UI needs behavior beyond normal form controls.

Course illustration
Course illustration

All Rights Reserved.