:checked
Matches a checked checkbox, a selected radio button, and a selected option in a select list.
Example
#.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;
}<label class="switch" style="position: relative; display: inline-flex; align-items: center; gap: 10px; cursor: pointer;">
<input type="checkbox">
<span class="track"></span>
Night mode
</label>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
#selector:checked { property: value; }Common uses
#- The text standing right after the checked field. Click the fields and watch the labels.
- The whole label with the checked field inside it, thanks to
:has(). - The control itself: checked fields get bigger and turn orange.
- 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
input:checked + span { color: #c4b5fd; font-weight: 700; }label:has(:checked)
:has().label:has(:checked) { background: #7c3aed; color: #fff; }input:checked
input:checked { accent-color: #f59e0b; scale: 1.3; }[checked]
[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-coloris enough. Reach forappearance: noneand 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: 0with positioning is enough. [checked]is only the initial state saved in the HTML. To react to clicks, always use:checked.
Related entries
#- A + BThe + sign selects element B that sits directly after element A and shares the same parent.
- :has()Selects an element based on what it contains or what follows it. Lets you style a parent according to its children.
- :disabledMatches disabled form elements, meaning ones that can’t be clicked, checked, or edited.
- [attribute]Selects elements by an HTML attribute and its value: exact, starting, ending, a fragment, or a word from a list.
Spotted a mistake or missing an example? Write to us.