A pseudo-class selects an element based on its state or its position in the document. They use a single colon, like :hover.

Logical pseudo-classes

  • :is(): matches any selector in a list. It shortens repeated selectors.
  • :where(): works like :is() but with zero specificity, so it is easy to override.
  • :not(): matches elements that do not match the selector inside.
  • :has(): selects a parent based on its children or following siblings. It is known as the parent selector.
css">/* :is() groups selectors */
:is( h1, h2, h3 ) a {
    color: orangered;
}

/* :where() has zero specificity */
:where( ul, ol ) {
    padding-left: 1.5em;
}

/* :not() excludes elements */
a:not( .button ) {
    text-decoration: underline;
}

/* :has() styles the parent */
.card:has( img ) {
    display: grid;
}

/* :has() with a form state */
form:has( input:invalid ) button {
    opacity: 0.5;
}

User action pseudo-classes

  • :hover: the pointer is over the element.
  • :active: the element is being pressed.
  • :focus: the element has keyboard or pointer focus.
  • :focus-visible: the element has focus and the browser decides a focus ring is needed, usually keyboard navigation.
  • :focus-within: the element or any of its descendants has focus.
a:hover { color: orangered; }
button:active { transform: scale( 0.97 ); }
input:focus { border-color: orangered; }
button:focus-visible { outline: 3px solid orangered; }
.lotgrafix-form:focus-within { box-shadow: 0 0 0 2px orangered; }

Structural pseudo-classes

  • :root: the top element of the document, usually html. Commonly used to declare CSS variables.
  • :empty: an element with no children and no text.
  • :first-child and :last-child: the first or last child of its parent.
  • :only-child: an element that is the only child of its parent.
  • :nth-child(): selects by position. Accepts a number, odd, even or a formula like 2n+1.
  • :nth-last-child(): the same, counting from the end.
  • :first-of-type, :last-of-type, :only-of-type and :nth-of-type(): the same ideas, but counting only elements of the same tag.
:root { --lotgrafix-color: orangered; }
p:empty { display: none; }
li:first-child { font-weight: bold; }
li:last-child { border-bottom: 0; }
tr:nth-child( even ) { background: #f5f5f5; }
li:nth-child( 3 ) { color: orangered; }
li:nth-last-child( 2 ) { color: blue; }
p:first-of-type { font-size: 1.2em; }
img:only-child { width: 100%; }

Link pseudo-classes

  • :link: links that have not been visited.
  • :visited: links that have been visited. Only a few properties, mainly color, can be changed for privacy reasons.
  • :any-link: matches both visited and unvisited links.
a:link { color: blue; }
a:visited { color: purple; }
a:any-link { text-decoration: none; }

Form pseudo-classes

  • :checked: checked checkboxes, radio buttons and selected options.
  • :disabled and :enabled: form controls that are disabled or enabled.
  • :required and :optional: fields with or without the required attribute.
  • :valid and :invalid: fields that pass or fail validation.
  • :user-invalid and :user-valid: the same, but only after the user has interacted with the field.
  • :read-only and :read-write: fields that can or cannot be edited.
  • :placeholder-shown: inputs currently showing their placeholder.
  • :in-range and :out-of-range: number inputs inside or outside their min and max.
  • :default: the default option or the default submit button of a form.
  • :indeterminate: checkboxes in an indeterminate state and progress bars without a value.
input:checked + label { font-weight: bold; }
button:disabled { opacity: 0.5; cursor: not-allowed; }
input:required { border-left: 3px solid orangered; }
input:user-invalid { border-color: red; }
input:user-valid { border-color: green; }
input:read-only { background: #eee; }
input:placeholder-shown { border-color: #ccc; }
input:out-of-range { color: red; }

Other useful pseudo-classes

  • :target: the element whose id matches the URL hash.
  • :lang(): elements by language, for example :lang( es ).
  • :dir(): elements by text direction, ltr or rtl.
  • :fullscreen: the element currently shown in fullscreen.
  • :modal: an element displayed as a modal, like a dialog opened with showModal().
  • :popover-open: a popover that is currently open.
  • :defined: elements, including custom elements, that have been defined.
section:target { background: #fffbe6; }
:lang( es ) q { quotes: "\00AB" "\00BB"; }
[dir="rtl"] .box { text-align: right; }
dialog:modal { border: 2px solid orangered; }
[popover]:popover-open { background: #fff; }
«
»