Skip to main content

CSS Pseudo-Classes and Pseudo-Elements Reference

A quick-lookup reference of every important pseudo-class and pseudo-element, with examples.

1. Pseudo-Classes: User Interaction

SelectorExampleDescription
:hovera:hoverMouse cursor is over element
:active.btn:activeElement currently being clicked
:focusinput:focusElement has keyboard/pointer focus
:focus-visiblea:focus-visibleFocus visible only for keyboard (not mouse)
:focus-within.form:focus-withinElement or any descendant has focus
:visiteda:visitedLink was already visited
:linka:linkUnvisited link

2. Pseudo-Classes: Structural

SelectorDescription
:first-childFirst sibling of its parent
:last-childLast sibling
:nth-child(n)nth child (also accepts odd, even, 2n+1)
:nth-last-child(n)From the end
:only-childOnly child of its parent
:first-of-typeFirst element of its type
:last-of-typeLast element of its type
:nth-of-type(n)nth element of its type
:emptyElement with no children (no whitespace either)
:rootThe root <html> element — use for global variables
/* Zebra stripe a table */
tr:nth-child(even) { background: rgba(255,255,255,0.05); }

/* First paragraph larger */
article p:first-of-type { font-size: var(--text-lg); }

3. Pseudo-Classes: Form State

SelectorApplies When
:checkedCheckbox / radio is checked
:disabledForm element is disabled
:enabledForm element is enabled
:requiredInput has required attribute
:optionalInput does not have required
:validInput value passes validation
:invalidInput value fails validation
:placeholder-shownPlaceholder text is visible (empty field)
:in-rangeNumber input within min/max range
:out-of-rangeNumber input outside min/max
:read-onlyInput with readonly attribute
input:valid { border-color: hsl(145, 65%, 45%); }
input:invalid { border-color: hsl(0, 75%, 55%); }
input:focus:invalid { box-shadow: 0 0 0 3px rgba(229,62,62,0.3); }

4. Pseudo-Classes: Matching

SelectorDescription
:not(selector)Every element that does NOT match
:is(s1, s2, s3)Matches any in the list; takes highest specificity
:where(s1, s2)Matches any in the list; always specificity zero
:has(child)Parent selector — element that contains a match
/* Style nav links EXCEPT the active one */
.nav__link:not(.active) { opacity: 0.7; }

/* Same heading styles, DRY */
:is(h1, h2, h3) { font-family: var(--font-heading); line-height: 1.2; }

/* Card containing an image gets less padding at top */
.card:has(img) { padding-top: 0; }

/* Highlight form section if ANY input is invalid */
.form-section:has(input:invalid) { border-color: red; }

5. Pseudo-Elements: The :: List

SelectorDescription
::beforeVirtual first child (requires content:)
::afterVirtual last child (requires content:)
::first-letterFirst character of block text
::first-lineFirst rendered line of block text
::selectionText highlighted by user
::placeholderInput placeholder text
::markerList item bullet or number
::backdropBehind a <dialog> element
::cueWebVTT cues in <video> tracks
::file-selector-buttonThe "Browse" button on <input type="file">
/* Custom drop cap */
article p:first-of-type::first-letter {
font-family: var(--font-heading);
font-size: 4rem;
float: left;
line-height: 0.75;
margin: 6px 10px 0 0;
color: var(--color-primary);
}

/* Highlight selection color */
::selection {
background: var(--color-primary);
color: white;
}

/* Custom bullet */
ul.checklist li::marker { content: '✓ '; color: var(--color-success); }

/* Style file input button */
input[type="file"]::file-selector-button {
background: var(--color-primary);
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: var(--radius-md);
cursor: pointer;
}