The essentials
Quick reference
One focused task per row. Jump to the related section for complete, working examples.
| Use | Syntax | Examples |
|---|---|---|
| Select by element type | article { max-inline-size: 70ch; } | View examples |
| Select by class | .notice { border-inline-start: 4px solid teal; } | View examples |
| Select by ID | #summary { scroll-margin-block-start: 2rem; } | View examples |
| Group selectors | h1, h2, h3 { text-wrap: balance; } | View examples |
| Match an attribute | button[disabled] { cursor: not-allowed; } | View examples |
| Match an exact value | input[type="email"] { inline-size: 100%; } | View examples |
| Match a token | [class~="featured"] { outline: 2px solid gold; } | View examples |
| Select a descendant | .card a { color: navy; } | View examples |
| Select a direct child | .menu > li { display: inline-block; } | View examples |
| Select the next sibling | h2 + p { margin-block-start: 0; } | View examples |
| Select later siblings | h2 ~ p { max-inline-size: 65ch; } | View examples |
| Style keyboard focus | .button:focus-visible {
outline: 3px solid currentColor;
} | View examples |
| Style checked controls | input:checked + label { font-weight: 700; } | View examples |
| Select the first child | .steps > li:first-child { margin-block-start: 0; } | View examples |
| Select alternating children | tbody > tr:nth-child(even) { background: #f3f4f6; } | View examples |
| Exclude a match | .tag:not(.tag--muted) { color: darkgreen; } | View examples |
| Group with zero weight | :where(nav, aside) a {
text-decoration-thickness: 0.12em;
} | View examples |
| Match through a descendant | .field:has(input:invalid) { border-color: crimson; } | View examples |
| Create generated decoration | .external::after { content: " ↗"; } | View examples |
| Style selected text | ::selection { background: gold; color: black; } | View examples |
Choose selectors that express stable meaning in the document and keep specificity easy to override. Start with classes and attributes, use combinators for real structural relationships, and reserve state and relational pseudo-classes for conditions the browser can evaluate directly.
Step by step
Detailed examples
Target types, reusable classes, IDs, and lists
Type selectors are useful for broad element defaults, while classes provide reusable styling hooks. IDs should remain unique and carry high specificity, so prefer them for fragment targets or rare one-off rules. In a selector list, an invalid selector can invalidate the entire rule unless it appears inside a forgiving construct such as :is() or :where().
article { max-inline-size: 70ch; }
.notice { border-inline-start: 4px solid teal; }
#summary { scroll-margin-block-start: 2rem; }
h1, h2, h3 { text-wrap: balance; } Select elements through stable attributes
Attribute selectors can match presence, exact values, or individual tokens. Prefer exact and token matching when possible because broad substring selectors can unintentionally match unrelated values. Attribute value case sensitivity depends on the document language and attribute, with optional flags available for explicit matching behavior.
button[disabled] { cursor: not-allowed; }
input[type="email"] { inline-size: 100%; }
[class~="featured"] { outline: 2px solid gold; } Express relationships with combinators
A descendant combinator allows any nesting depth, while the child combinator requires an immediate parent. Adjacent and subsequent sibling combinators match elements that share a parent and occur after the first selector. Use the narrowest relationship that reflects the markup without depending on fragile incidental nesting.
.card a { color: navy; }
.menu > li { display: inline-block; }
h2 + p { margin-block-start: 0; }
h2 ~ p { max-inline-size: 65ch; } Respond to interaction and control state
Pseudo-classes match state that may not be represented by a static attribute. Use :focus-visible to preserve a clear keyboard focus indicator, and treat :checked as a styling enhancement rather than a replacement for semantic form controls and labels.
.button:focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}
input:checked + label { font-weight: 700; } Note: Do not remove the browser focus outline unless the replacement remains clearly visible in every theme and contrast mode.
Match elements by sibling position
Structural pseudo-classes use one-based positions in the element tree. :first-child requires the element to be its parent's first child, while :nth-child() follows the An+B pattern across all element siblings unless an of selector is supplied. Changes to sibling markup can therefore change which element matches.
.steps > li:first-child { margin-block-start: 0; }
tbody > tr:nth-child(even) { background: #f3f4f6; } Combine, exclude, and relate selectors
:not() excludes its selector-list argument, :where() groups selectors with zero specificity, and :has() matches an element relative to descendants or other related elements. The arguments to :is(), :not(), and :has() affect specificity through their most specific selector, while :where() always contributes zero specificity.
.tag:not(.tag--muted) { color: darkgreen; }
:where(nav, aside) a { text-decoration-thickness: 0.12em; }
.field:has(input:invalid) { border-color: crimson; } Note: Use :has() to reflect meaningful relationships, but avoid very broad selectors that force the browser and future maintainers to inspect more of the document than necessary.
Style generated and selected content
Pseudo-elements represent portions or generated abstractions that are not ordinary DOM elements. Generated content should remain decorative because it may not be exposed consistently to assistive technology, and important words or controls must stay in the HTML.
.external::after { content: " ↗"; }
::selection { background: gold; color: black; } Local code tester
Try CSS selectors
Edit the markup and selectors locally to see how attributes, state, structure, and relationships affect matching.
Sources and further reading
References
Authoritative documentation used to verify and expand this cheat sheet.
Help us improve
Found a typo or missing example?
Tell us what would make this cheat sheet clearer, more complete, or more useful.



