CSS Cheatsheet

Selectors

Use this CSS reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Basic Selectors

SelectorMatches
*Every element (universal)
divAll <div> elements (type)
.classElements with that class
#idThe element with that id
[attr]Elements that have the attribute
* { box-sizing: border-box; }
p { margin-bottom: 1em; }
.highlight { background: yellow; }
#logo { width: 120px; }
[disabled] { opacity: 0.5; }

Combinators

CombinatorSyntaxMatches
DescendantA BB anywhere inside A
ChildA > BB that is a direct child of A
Adjacent siblingA + BB immediately after A (same parent)
General siblingA ~ BAll B after A (same parent)
Column`coltd`td in that column (limited support)
nav a { text-decoration: none; }       /* any <a> inside nav */
ul > li { list-style: disc; }          /* direct li children */
h2 + p { margin-top: 0; }             /* p right after h2 */
.open ~ .panel { display: block; }    /* .panel siblings after .open */

Attribute Selectors

SelectorMatches
[attr]Has the attribute
[attr="val"]Exact value
[attr~="val"]Space-separated list contains val
[attr|="val"]val or val- (language codes)
[attr^="val"]Starts with val
[attr$="val"]Ends with val
[attr*="val"]Contains val anywhere
[attr="val" i]Case-insensitive match
[attr="val" s]Case-sensitive match (explicit)
a[href]                  { color: blue; }
a[href="https://x.com"]  { font-weight: bold; }
input[type="text"]       { border: 1px solid #ccc; }
a[href^="https"]         { /* secure links */ }
a[href$=".pdf"]          { /* pdf links */ }
img[src*="thumb"]        { width: 80px; }
[lang|="en"]             { quotes: '"' '"'; }
input[placeholder~="email" i] { /* case-insensitive */ }

Grouping and the :is() / :where() / :not() / :has() Family

/* Grouping — comma list */
h1, h2, h3 { font-weight: 600; }

/* :is() — matches any selector in list; takes highest specificity of list */
:is(h1, h2, h3) > a { color: inherit; }
:is(article, section) :is(h2, h3) { margin-top: 1.5em; }

/* :where() — same as :is() but ZERO specificity */
:where(header, footer) a { text-decoration: none; }

/* :not() — excludes; accepts selector list */
a:not([href]) { color: gray; }
li:not(:last-child) { border-bottom: 1px solid #eee; }
:not(h1, h2) { font-size: 1rem; }

/* :has() — parent/relational selector (CSS Selectors 4) */
form:has(:invalid) { border-color: red; }
h2:has(+ p) { margin-bottom: 0.5rem; }
article:has(> img:first-child) { padding-top: 0; }
figure:not(:has(figcaption)) { opacity: 0.8; }

Pseudo-classes — State

Pseudo-classMatches
:hoverPointer over element
:focusElement has keyboard/pointer focus
:focus-visibleFocus visible per UA heuristic
:focus-withinElement or descendant has focus
:activeBeing activated (click)
:visitedVisited link
:linkUnvisited link
:any-linkAny :link or :visited
:targetID matches URL fragment
:checkedCheckbox/radio/option is checked
:indeterminateIndeterminate state
:disabledDisabled form element
:enabledEnabled form element
:requiredInput with required attribute
:optionalInput without required
:validValid form value
:invalidInvalid form value
:in-rangeValue within min/max
:out-of-rangeValue outside min/max
:placeholder-shownInput showing placeholder
:read-onlyRead-only element
:read-writeEditable element
:defaultDefault form element in group
:fullscreenElement in fullscreen mode
:modalElement in modal state (<dialog>)
a:hover { text-decoration: underline; }
button:focus-visible { outline: 2px solid blue; }
input:invalid { border-color: red; }
details:not([open]) summary { cursor: pointer; }
:target { scroll-margin-top: 4rem; }

Pseudo-classes — Tree Structure

Pseudo-classMatches
:first-childFirst child of its parent
:last-childLast child of its parent
:only-childOnly child of its parent
:nth-child(n)nth child (1-indexed)
:nth-last-child(n)nth from end
:first-of-typeFirst of that element type
:last-of-typeLast of that element type
:only-of-typeOnly element of that type
:nth-of-type(n)nth of that type
:nth-last-of-type(n)nth of type from end
:emptyNo children (including text)
:rootRoot element (usually <html>)
:scopeScoping element
li:first-child { margin-top: 0; }
li:last-child  { border-bottom: none; }
tr:nth-child(even)  { background: #f5f5f5; }
tr:nth-child(odd)   { background: white; }
tr:nth-child(3n+1)  { /* 1st, 4th, 7th… */ }
tr:nth-child(-n+3)  { /* first 3 */ }
p:nth-of-type(2)    { color: gray; }
p:empty             { display: none; }

nth-child Formula Reference

ExpressionSelects
odd1, 3, 5…
even2, 4, 6…
3exactly the 3rd
2nevery 2nd (2, 4, 6…)
2n+1every odd (1, 3, 5…)
3n+22, 5, 8, 11…
-n+3first 3 (3, 2, 1)
n+44th and beyond

nth-child with of S (CSS Selectors 4)

/* Every even .card child */
:nth-child(even of .card) { background: #f0f0f0; }

Pseudo-elements

Pseudo-elementGenerates
::beforeInserted before element content
::afterInserted after element content
::first-lineFirst rendered line of text
::first-letterFirst letter of text
::selectionUser-selected text
::markerList item marker
::placeholderPlaceholder text
::backdropBehind fullscreen/dialog element
::spelling-errorMisspelled text (limited support)
::grammar-errorGrammar error (limited support)
::file-selector-button<input type="file"> button
::cueWebVTT cue text
::slotted(sel)Slotted Shadow DOM content
::part(name)Shadow DOM part
.btn::before { content: "→ "; }
p::first-letter { font-size: 2em; float: left; }
::selection { background: #b3d4fc; color: #000; }
li::marker { color: teal; font-weight: bold; }
input::placeholder { color: #aaa; font-style: italic; }
dialog::backdrop { background: rgba(0,0,0,0.5); }
input[type="file"]::file-selector-button { padding: 0.4rem 0.8rem; }

Specificity Summary

Selector typeValue
Inline style=""1-0-0-0
#id0-1-0-0
.class, [attr], :pseudo-class0-0-1-0
element, ::pseudo-element0-0-0-1
*, combinators0-0-0-0
:is(), :not(), :has()specificity of most specific arg
:where()always 0-0-0-0
/* Specificity: 0-1-1-2 */
#nav .menu li a { color: red; }

/* Force without !important — layer it instead */
@layer utilities {
  .hidden { display: none; }
}

Scoping with :scope and @scope

/* :scope in a stylesheet = root element */
:scope { --brand: teal; }

/* @scope (CSS Scoping Level 1) */
@scope (.card) to (.card__footer) {
  /* styles apply inside .card but not inside .card__footer */
  p { color: inherit; }
}

Selector Performance Tips

  • Browsers read selectors right to left — the rightmost part is the key selector.
  • Avoid deep descendant chains (div div div span).
  • Prefer class selectors over attribute or type selectors for hot paths.
  • Universal * in combinators (* + * lobotomized owl) is fine at small scale.