CSS Pseudo-classes
Pseudo-classes select elements based on their state (hover, focus, active) or position in the DOM (first-child, nth-child). They add interactivity and dynamic styling without JavaScript.
35 min•By Priygop Team•Last updated: Feb 2026
Common Pseudo-classes
- :hover — Mouse over the element. The most used pseudo-class for interactive effects
- :focus — Element is focused (clicked or tabbed to). Essential for accessibility — never remove without replacement
- :focus-visible — Only shows focus ring for keyboard navigation, not mouse clicks. Better UX than :focus
- :active — Element is being clicked/pressed. Use for button press feedback
- :first-child / :last-child — First/last element among siblings. Remove borders, margins from first/last items
- :nth-child(n) — Pattern matching: :nth-child(2n) even, :nth-child(3n+1) every 3rd starting from 1st, :nth-child(odd) odd
- :not(selector) — Negation: :not(:last-child) { margin-bottom: 16px; } — all items except last get margin
- :has(selector) — Parent selector (NEW!): .card:has(img) { grid-column: span 2; } — cards with images span 2 columns
- :is(selector) — Group selectors: :is(h1, h2, h3) { color: navy; } — replaces repetitive comma-separated selectors
- :where(selector) — Like :is() but with 0 specificity. Perfect for reset/default styles that are easy to override
Pseudo-class Code Examples
Example
/* Interactive form inputs */
input:focus {
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2);
outline: none;
}
input:focus-visible {
outline: 2px solid #667eea; /* Keyboard focus visible */
}
input:valid { border-color: #2ecc71; }
input:invalid:not(:placeholder-shown) { border-color: #e74c3c; }
/* Zebra striping with nth-child */
tr:nth-child(even) { background: #f8f9fa; }
tr:hover { background: #e8f0fe; }
/* Remove last item border */
.list li:not(:last-child) {
border-bottom: 1px solid #eee;
}
/* :has() — parent selector */
.card:has(.badge) {
border: 2px solid #E44D26; /* Highlight cards WITH badges */
}
/* :is() for cleaner selectors */
:is(h1, h2, h3) {
font-family: 'Inter', sans-serif;
color: #1a1a2e;
}
:is(h1, h2, h3):hover {
color: #E44D26;
}
/* Interactive link states (order matters: LVFHA) */
a:link { color: #667eea; }
a:visited { color: #764ba2; }
a:focus { outline: 2px solid #667eea; }
a:hover { color: #E44D26; }
a:active { color: #c0392b; }