CSS pseudo-classPseudo-classes

:checked

Matches a checked checkbox, a selected radio button, and a selected option in a select list.

On this page

Example

#
CSS
.switch input {
  position: absolute;
  opacity: 0;
}

.track {
  width: 44px;
  padding: 3px;
  border-radius: 999px;
  background: #3f3f46;
  transition: background-color 0.2s;
}

.track::before {
  content: "";
  display: block;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  transition: translate 0.2s;
}

.switch input:checked + .track {
  background: #7c3aed;
}

.switch input:checked + .track::before {
  translate: 20px 0;
}

.switch input:focus-visible + .track {
  outline: 2px solid #a78bfa;
  outline-offset: 2px;
}
Preview

Click the switch, or tab to it with the keyboard and press space. The real checkbox is invisible, but it still works.

Definition and usage

#

The :checked pseudo-class reflects the current state of a control: it matches <input type="checkbox"> and <input type="radio"> when they’re checked, and selected <option> elements. It changes live, the moment of the click, with no JavaScript at all.

That’s different from the [checked] attribute selector. The HTML attribute only describes the initial state and doesn’t change after a click, while :checked always reflects the current state.

The control itself can only be styled to a limited extent, which is why :checked is most often paired with the sibling combinator (input:checked + label) or with :has(), to change a label, a card, or an entire row. The simplest way to change the color of the control itself is accent-color.

Syntax

#
Syntax
selector:checked { property: value; }

Common uses

#
  • input:checked + span

    The text standing right after the checked field. Click the fields and watch the labels.
  • label:has(:checked)

    The whole label with the checked field inside it, thanks to :has().
  • input:checked

    The control itself: checked fields get bigger and turn orange.
  • [checked]

    For comparison, the attribute selector. The red outline stays on fields checked in the HTML, even once you uncheck them.

Common uses in practice

#

input:checked + span

The text standing right after the checked field. Click the fields and watch the labels.
input:checked + span { color: #c4b5fd; font-weight: 700; }

label:has(:checked)

The whole label with the checked field inside it, thanks to :has().
label:has(:checked) { background: #7c3aed; color: #fff; }

input:checked

The control itself: checked fields get bigger and turn orange.
input:checked { accent-color: #f59e0b; scale: 1.3; }

[checked]

For comparison, the attribute selector. The red outline stays on fields checked in the HTML, even once you uncheck them.
[checked] { outline: 2px dashed #f43f5e; outline-offset: 2px; }

Browser support

#

Widely available

Works in all modern browsers, phones included. You can use it without worry.

  • Chrome
  • Edge
  • Firefox
  • Safari

Good practices

#
  • To change the color of the checkbox itself, accent-color is enough. Reach for appearance: none and a fully custom look only when you need more than that.
  • When hiding the real field, don’t use display: none. The field would then disappear for the keyboard and screen readers too. opacity: 0 with positioning is enough.
  • [checked] is only the initial state saved in the HTML. To react to clicks, always use :checked.

Related entries

#

Spotted a mistake or missing an example? Write to us.