A
AiTechWorlds
AiTechWorlds
Selectors tell CSS which elements to style. Understanding how specificity determines which rule wins when selectors conflict is one of the most important skills for writing maintainable CSS.
/* Universal */
* { box-sizing: border-box; }
/* Type (element) */
h1 { font-size: 2rem; }
p { line-height: 1.6; }
/* Class */
.card { border-radius: 8px; }
.btn-primary { background: blue; }
/* ID */
#nav { position: sticky; }
#hero { min-height: 100vh; }
/* Attribute */
input[type="email"] { border: 1px solid #ccc; }
a[href^="https"] { color: green; } /* starts with */
a[href$=".pdf"] { color: red; } /* ends with */
a[href*="example"] { font-weight: bold; } /* contains */
[data-theme="dark"] { background: #1a1a1a; }
/* Descendant (space) — any level deep */
.card img { border-radius: 4px; }
/* Child (>) — direct children only */
.nav > li { display: flex; }
/* Adjacent sibling (+) — immediately after */
h2 + p { margin-top: 0; }
/* General sibling (~) — all following siblings */
h2 ~ p { color: #666; }
/* State */
a:hover { color: blue; }
a:active { opacity: 0.8; }
a:focus { outline: 2px solid blue; }
a:visited { color: purple; }
input:focus { border-color: blue; }
input:disabled { opacity: 0.5; cursor: not-allowed; }
input:checked + label { font-weight: bold; }
/* Structural */
li:first-child { border-top: none; }
li:last-child { border-bottom: none; }
li:nth-child(2) { background: lightyellow; }
li:nth-child(even) { background: #f9f9f9; }
li:nth-child(3n+1) { color: red; } /* every 3rd starting at 1 */
li:nth-last-child(2) { /* 2nd from end */ }
p:only-child { /* only if it's the only child */ }
/* Content */
p:empty { display: none; }
p:not(.special) { color: #333; }
:is(h1, h2, h3) { line-height: 1.2; } /* matches any in list */
:where(h1, h2, h3) { line-height: 1.2; } /* same but 0 specificity */
:has(img) { border: 1px solid #ccc; } /* parent selector! */
/* Form states */
input:valid { border-color: green; }
input:invalid { border-color: red; }
input:required { border-left: 3px solid orange; }
input:placeholder-shown { font-style: italic; }
/* Insert content before/after */
.required::before {
content: "* ";
color: red;
}
blockquote::before {
content: "\201C"; /* open quote " */
font-size: 3rem;
color: #ccc;
}
/* Style parts of text */
p::first-line { font-variant: small-caps; }
p::first-letter { font-size: 2em; float: left; }
/* Text selection */
::selection {
background: #4a90e2;
color: white;
}
/* Placeholder text */
input::placeholder { color: #aaa; font-style: italic; }
/* Scrollbar (Webkit/Blink only) */
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-thumb { background: #888; border-radius: 4px; }
When two rules target the same element, specificity determines which wins. It's calculated as a three-part score: (IDs, Classes/Attributes/Pseudoclasses, Types/Pseudoelements).
Selector IDs Classes Types → Score
────────────────────────────────────────────────────────────────
* 0 0 0 → 0-0-0
p 0 0 1 → 0-0-1
.class 0 1 0 → 0-1-0
#id 1 0 0 → 1-0-0
p.class 0 1 1 → 0-1-1
#id .class p 1 1 1 → 1-1-1
inline style="..." → 1-0-0-0 (wins!)
!important → override all
/* Lower specificity — 0-0-1 */
p { color: blue; }
/* Higher specificity — 0-1-1 — this wins */
.intro p { color: red; }
/* Same specificity — later rule wins */
.intro p { color: red; }
.content p { color: green; } /* ← wins if both match */
/* Order of precedence (highest to lowest): */
/* 1. !important (avoid — makes maintenance hell) */
.override { color: red !important; }
/* 2. Inline styles */
/* <p style="color: blue;"> */
/* 3. IDs */
#header { color: blue; }
/* 4. Classes, attributes, pseudo-classes */
.nav-link:hover { color: blue; }
[type="text"] { color: blue; }
/* 5. Elements, pseudo-elements */
p { color: blue; }
p::first-line { color: blue; }
/* 6. Universal, combinators */
* { color: blue; }
/* Write selectors as low-specificity as possible */
/* Bad — hard to override */
nav ul li a.active { color: blue; }
/* Better — one class does the job */
.nav-active { color: blue; }
/* Use :is() to reduce repetition without adding specificity */
:is(h1, h2, h3, h4) a { color: inherit; }
/* CSS Layers (modern) — explicit specificity control */
@layer base, components, utilities;
@layer base {
p { color: #333; }
}
@layer utilities {
.text-red { color: red; } /* wins over base layer regardless of specificity */
}
Next lesson: The Box Model & Display Modes — how CSS lays out elements on the page.
Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises