This is a searchable reference for CSS pseudo-classes — the single-colon selectors that match elements based on their state, position in the document tree, or relationship to other elements. It covers the structural, input-state, linguistic, location and functional pseudo-classes you reach for when styling links, form controls, list items and interactive widgets.
How it works
A pseudo-class is written as a colon followed by a keyword, optionally with arguments in parentheses. Unlike a class attribute, it is not present in your markup — the browser evaluates it dynamically. State pseudo-classes such as :hover, :focus and :checked react to user interaction or form state. Tree-structural ones such as :first-child and :nth-child() match by position among siblings. The :nth-child() family uses an An+B micro-syntax: A is the cycle size, n counts from zero, and B is the offset, so :nth-child(3n+1) matches the 1st, 4th, 7th child and so on. Functional pseudo-classes — :is(), :where(), :not() and :has() — take selector lists and combine logic; :has() is the long-awaited relational (“parent”) selector.
Specificity and tips
Most pseudo-classes add the weight of a class (the middle digit of specificity). The exceptions matter: :where() always adds zero, and :is() / :not() / :has() inherit the specificity of their most specific argument. Use :focus-visible instead of :focus so you only show focus rings for keyboard users, and reach for :focus-within to style a container when any child is focused. Note that :empty treats whitespace as content, so a node containing only spaces will not match.
Example
/* Zebra-stripe a table */
tr:nth-child(even) { background: #f5f5f5; }
/* Style a card that contains an image */
.card:has(img) { padding-top: 0; }
/* Low-specificity reset that is easy to override */
:where(ul, ol) { margin: 0; padding: 0; }
Everything runs in your browser; nothing you search is uploaded.