CSS Selectors & Specificity
Target elements precisely with element, class, ID, pseudo-class selectors, and understand specificity
Knowledge Debt detected
You can study this freely — but your score may plateau if these foundations have gaps. The Mastery badge requires them to be solid.
Explanation
CSS selectors define which HTML elements a rule applies to. Specificity determines which rule wins when multiple rules target the same element.
Basic selectors:
css /* Element selector — all <p> tags */ p { color: gray; } /* Class selector — elements with class="card" */ .card { background: white; } /* ID selector — the element with id="hero" */ #hero { font-size: 3rem; } /* Universal selector — everything */ * { box-sizing: border-box; }
Combinators:
css /* Descendant: any <a> inside .nav */ .nav a { text-decoration: none; } /* Child: only direct <li> children of <ul> */ ul > li { margin-bottom: 8px; } /* Adjacent sibling: <p> immediately after <h2> */ h2 + p { font-size: 1.1rem; } /* General sibling: all <p> after an <h2> in the same parent */ h2 ~ p { color: #555; }
Pseudo-classes — state-based:
css a:hover { color: blue; } /* mouse over */ a:focus { outline: 2px solid; } /* keyboard focus */ a:visited { color: purple; } /* visited link */ input:disabled { opacity: 0.5; } /* disabled state */ li:first-child { font-weight: bold; } /* first item */ li:last-child { border: none; } /* last item */ li:nth-child(2) { background: #f0f; } /* 2nd item */ li:nth-child(odd) { background: #eee; } /* alternating rows */
Pseudo-elements — style part of an element:
css p::first-line { font-weight: bold; } p::first-letter { font-size: 2em; } .card::before { content: "★ "; color: gold; } .card::after { content: ""; display: block; clear: both; }
Specificity — which rule wins:
| Selector type | Specificity score | |---|---| | Inline style | 1000 | | ID (#id) | 100 | | Class (.cls), attribute, pseudo-class | 10 | | Element (p, div), pseudo-element | 1 |
p { color: gray; } /* score: 1 */
.card p { color: blue; } /* score: 11 — wins */
#hero p { color: red; } /* score: 101 — wins over above */`!important` overrides all specificity — use only as a last resort; it makes debugging painful.
Examples
Common selector patterns
Combining element + class selectors (`.primary`) is more specific than element alone; `:nth-child(even)` creates zebra-stripe tables without JS
/* Style all buttons */
button { padding: 8px 16px; border-radius: 4px; }
/* Only "primary" variant */
button.primary { background: #6366f1; color: white; }
/* Nested: links inside nav only */
nav a { font-weight: 600; text-decoration: none; }
nav a:hover { text-decoration: underline; }
/* Alternating table rows */
tr:nth-child(even) { background: #f9fafb; }
/* Input when it has focus */
input:focus { outline: 2px solid #6366f1; outline-offset: 2px; }
/* Required inputs get a red left border */
input:required { border-left: 3px solid #ef4444; }Specificity conflict example
Keeping selectors short (1-2 levels deep) avoids specificity wars — flat class names like BEM (.article__body) stay at score 10
/* Specificity 1: element selector */
p { color: black; }
/* Specificity 11: class + element */
.article p { color: #333; }
/* Specificity 111: class + class + element — but BAD practice */
.blog .article p { color: #555; }
/* Better: use a BEM class instead of chained selectors */
.article__body { color: #333; }
/* Never do this unless fixing third-party CSS */
p { color: purple !important; }How well did you understand this?
Next in CSS & Styling
The CSS Box Model