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
| Selector | Matches |
|---|---|
* | Every element (universal) |
div | All <div> elements (type) |
.class | Elements with that class |
#id | The 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
| Combinator | Syntax | Matches | ||
|---|---|---|---|---|
| Descendant | A B | B anywhere inside A | ||
| Child | A > B | B that is a direct child of A | ||
| Adjacent sibling | A + B | B immediately after A (same parent) | ||
| General sibling | A ~ B | All B after A (same parent) | ||
| Column | `col | td` | 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
| Selector | Matches |
|---|---|
[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-class | Matches |
|---|---|
:hover | Pointer over element |
:focus | Element has keyboard/pointer focus |
:focus-visible | Focus visible per UA heuristic |
:focus-within | Element or descendant has focus |
:active | Being activated (click) |
:visited | Visited link |
:link | Unvisited link |
:any-link | Any :link or :visited |
:target | ID matches URL fragment |
:checked | Checkbox/radio/option is checked |
:indeterminate | Indeterminate state |
:disabled | Disabled form element |
:enabled | Enabled form element |
:required | Input with required attribute |
:optional | Input without required |
:valid | Valid form value |
:invalid | Invalid form value |
:in-range | Value within min/max |
:out-of-range | Value outside min/max |
:placeholder-shown | Input showing placeholder |
:read-only | Read-only element |
:read-write | Editable element |
:default | Default form element in group |
:fullscreen | Element in fullscreen mode |
:modal | Element 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-class | Matches |
|---|---|
:first-child | First child of its parent |
:last-child | Last child of its parent |
:only-child | Only child of its parent |
:nth-child(n) | nth child (1-indexed) |
:nth-last-child(n) | nth from end |
:first-of-type | First of that element type |
:last-of-type | Last of that element type |
:only-of-type | Only element of that type |
:nth-of-type(n) | nth of that type |
:nth-last-of-type(n) | nth of type from end |
:empty | No children (including text) |
:root | Root element (usually <html>) |
:scope | Scoping 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
| Expression | Selects |
|---|---|
odd | 1, 3, 5… |
even | 2, 4, 6… |
3 | exactly the 3rd |
2n | every 2nd (2, 4, 6…) |
2n+1 | every odd (1, 3, 5…) |
3n+2 | 2, 5, 8, 11… |
-n+3 | first 3 (3, 2, 1) |
n+4 | 4th and beyond |
nth-child with of S (CSS Selectors 4)
/* Every even .card child */ :nth-child(even of .card) { background: #f0f0f0; }
Pseudo-elements
| Pseudo-element | Generates |
|---|---|
::before | Inserted before element content |
::after | Inserted after element content |
::first-line | First rendered line of text |
::first-letter | First letter of text |
::selection | User-selected text |
::marker | List item marker |
::placeholder | Placeholder text |
::backdrop | Behind fullscreen/dialog element |
::spelling-error | Misspelled text (limited support) |
::grammar-error | Grammar error (limited support) |
::file-selector-button | <input type="file"> button |
::cue | WebVTT 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 type | Value |
|---|---|
Inline style="" | 1-0-0-0 |
#id | 0-1-0-0 |
.class, [attr], :pseudo-class | 0-0-1-0 |
element, ::pseudo-element | 0-0-0-1 |
*, combinators | 0-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.