Skip to content

CSS Tutorial CSS Pseudo-classes

CSS :checked, :disabled and :required

Lesson 121 of 182 2 min read By Deepak Paswan Updated Oct 4, 2026

Form fields have states that CSS can detect, with no JavaScript.

Pseudo-classMatches
:checkedA checked checkbox or radio button, or a selected option
:disabledA control that cannot be used
:enabledThe opposite
:requiredA field marked required
:optionalA field that is not required
:valid, :invalidPassing or failing its own validation rules
:placeholder-shownA field that is still showing its placeholder

:checked in action

index.html
HTML
<style>
  input[type="checkbox"]:checked + label { color: #1a5276; font-weight: bold; text-decoration: line-through; }
  label { margin-left: 6px; }
</style>
<input type="checkbox" id="a"><label for="a">Buy a notebook</label><br>
<input type="checkbox" id="b" checked><label for="b">Buy a pen</label>

The + is the adjacent sibling selector: the label comes straight after the checkbox, so CSS can react to the checkbox state.

:disabled and :required

index.html
HTML
<style>
  input:disabled { background: #eee; color: #888; cursor: not-allowed; }
  input:required { border-left: 4px solid #d94a00; }
  input { padding: 6px; margin: 4px; }
</style>
<input placeholder="Required field" required>
<input placeholder="Optional field">
<input placeholder="Disabled field" disabled>

A toggle switch with no JavaScript

A hidden checkbox plus a styled label makes a switch:

index.html
HTML
<style>
  .switch input { position: absolute; opacity: 0; }
  .switch label { display: inline-block; width: 52px; height: 28px; background: #bbb; border-radius: 999px; position: relative; cursor: pointer; transition: background .2s; }
  .switch label::after { content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; background: #fff; border-radius: 50%; transition: transform .2s; }
  .switch input:checked + label { background: #27ae60; }
  .switch input:checked + label::after { transform: translateX(24px); }
  .switch input:focus-visible + label { outline: 3px solid #1a5276; outline-offset: 2px; }
</style>
<div class="switch"><input type="checkbox" id="sw"><label for="sw" aria-label="Notifications"></label></div>

The checkbox is still there and focusable, only invisible. This is why keyboard users and screen readers can still use it. More about styling forms in Form Validation States.