Day 2: Selectors and the Cascade
What You'll Learn Today
- Combinator selectors and grouping
- Attribute selectors
- Pseudo-classes and pseudo-elements
- Specificity calculation
- The cascade and source order
- Inheritance
Combinator Selectors
Descendant Selector (Space)
/* All <p> elements inside <article> */
article p {
line-height: 1.8;
}
Child Selector (>)
/* Only direct <li> children of <ul> */
ul > li {
list-style: disc;
}
Adjacent Sibling Selector (+)
/* The <p> immediately after an <h2> */
h2 + p {
font-size: 1.2rem;
color: #64748b;
}
General Sibling Selector (~)
/* All <p> elements that follow an <h2> */
h2 ~ p {
margin-left: 16px;
}
flowchart TB
subgraph Combinators["Combinator Selectors"]
Desc["Descendant<br>A B"]
Child["Child<br>A > B"]
Adj["Adjacent Sibling<br>A + B"]
Gen["General Sibling<br>A ~ B"]
end
style Desc fill:#3b82f6,color:#fff
style Child fill:#22c55e,color:#fff
style Adj fill:#f59e0b,color:#fff
style Gen fill:#8b5cf6,color:#fff
Grouping Selector (,)
h1, h2, h3 {
color: #1e293b;
}
Attribute Selectors
/* <a> with an href attribute */
a[href] {
color: #3b82f6;
}
/* External links */
a[target="_blank"] {
text-decoration: underline;
}
/* Links starting with https */
a[href^="https"] {
color: #22c55e;
}
/* Links ending in .pdf */
a[href$=".pdf"] {
color: #ef4444;
}
/* Links containing "example" */
a[href*="example"] {
font-weight: bold;
}
| Selector | Meaning |
|---|---|
[attr] |
Attribute exists |
[attr="val"] |
Exact match |
[attr^="val"] |
Starts with |
[attr$="val"] |
Ends with |
[attr*="val"] |
Contains |
Pseudo-Classes
Link and Interaction States
a:link { color: #3b82f6; } /* unvisited */
a:visited { color: #8b5cf6; } /* visited */
a:hover { color: #2563eb; } /* mouse over */
a:active { color: #1d4ed8; } /* being clicked */
a:focus { outline: 2px solid #3b82f6; } /* focused */
Order matters: Write link pseudo-classes in LVHA order β Link, Visited, Hover, Active β to ensure they work correctly.
Structural Pseudo-Classes
li:first-child { font-weight: bold; }
li:last-child { border-bottom: none; }
li:nth-child(2) { color: #3b82f6; }
li:nth-child(odd) { background: #f8fafc; }
li:nth-child(even) { background: #f1f5f9; }
li:nth-child(3n) { color: #ef4444; } /* every 3rd item */
| Pseudo-Class | Description |
|---|---|
:first-child |
First child element |
:last-child |
Last child element |
:nth-child(n) |
The nth child |
:nth-child(odd/even) |
Odd or even children |
:not(selector) |
Elements that do NOT match |
:empty |
Elements with no children |
:focus-visible |
Keyboard-triggered focus |
The :not() Pseudo-Class
/* Add a bottom border to every item except the last */
li:not(:last-child) {
border-bottom: 1px solid #e2e8f0;
}
Pseudo-Elements
/* Enlarge the first letter */
p::first-letter {
font-size: 2rem;
font-weight: bold;
}
/* Bold the first line */
p::first-line {
font-weight: bold;
}
/* Insert content before an element */
.required::before {
content: "* ";
color: #ef4444;
}
/* Insert content after an element */
a[target="_blank"]::after {
content: " β";
}
| Pseudo-Element | Description |
|---|---|
::before |
Insert content before the element |
::after |
Insert content after the element |
::first-letter |
The first letter |
::first-line |
The first line |
::placeholder |
Placeholder text in inputs |
::selection |
User-selected text |
Specificity
This is one of the most important concepts in CSS. When multiple rules target the same element, the rule with the highest specificity wins.
Calculating Specificity
flowchart LR
subgraph Specificity["Specificity Weights"]
Inline["Inline Style<br>1,0,0,0"]
ID["ID Selector<br>0,1,0,0"]
Class["Class / Pseudo-class<br>0,0,1,0"]
Elem["Element / Pseudo-element<br>0,0,0,1"]
end
Inline --> ID --> Class --> Elem
style Inline fill:#ef4444,color:#fff
style ID fill:#f59e0b,color:#fff
style Class fill:#22c55e,color:#fff
style Elem fill:#3b82f6,color:#fff
| Selector | Specificity | Breakdown |
|---|---|---|
p |
0,0,0,1 | 1 element |
.highlight |
0,0,1,0 | 1 class |
p.highlight |
0,0,1,1 | 1 class + 1 element |
#main |
0,1,0,0 | 1 ID |
#main .highlight p |
0,1,1,1 | 1 ID + 1 class + 1 element |
Example in Action
p { color: black; } /* 0,0,0,1 */
.text { color: blue; } /* 0,0,1,0 β wins over element */
#intro { color: red; } /* 0,1,0,0 β wins over class */
<p id="intro" class="text">This text will be red.</p>
!important: Addingcolor: green !important;overrides all specificity, but use it sparingly. It makes debugging significantly harder.
The Cascade
The "Cascade" in CSS is the algorithm that determines which styles ultimately apply when multiple rules compete.
Order of Priority
flowchart TB
A["1. Importance<br>!important > normal"] --> B["2. Specificity<br>ID > Class > Element"]
B --> C["3. Source Order<br>Later rules win"]
style A fill:#ef4444,color:#fff
style B fill:#f59e0b,color:#fff
style C fill:#22c55e,color:#fff
/* Source order: the last rule wins when specificity is equal */
p { color: blue; }
p { color: red; } /* this one applies */
Inheritance
Some CSS properties are automatically passed down from parent to child elements.
Properties That Inherit
body {
font-family: sans-serif; /* inherited */
color: #333; /* inherited */
line-height: 1.6; /* inherited */
}
Properties That Do NOT Inherit
.box {
border: 1px solid #ccc; /* not inherited */
padding: 16px; /* not inherited */
margin: 16px; /* not inherited */
background: #f0f0f0; /* not inherited */
}
| Inherited | Not Inherited |
|---|---|
color |
margin |
font-family |
padding |
font-size |
border |
line-height |
background |
text-align |
width / height |
cursor |
display |
Forcing Inheritance
.box {
border: inherit; /* inherit border from parent */
}
Practice: Card Layout
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Selector Practice</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>News Feed</h1>
<article class="card">
<h2>Article Title 1</h2>
<p class="meta">January 29, 2026 | <span class="tag">CSS</span></p>
<p>Article body text goes here...</p>
<a href="#" class="read-more">Read more</a>
</article>
<article class="card">
<h2>Article Title 2</h2>
<p class="meta">January 28, 2026 | <span class="tag">HTML</span></p>
<p>Article body text goes here...</p>
<a href="#" class="read-more">Read more</a>
</article>
</body>
</html>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: sans-serif;
line-height: 1.6;
color: #333;
max-width: 600px;
margin: 0 auto;
padding: 32px 16px;
}
h1 {
margin-bottom: 24px;
}
.card {
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 24px;
margin-bottom: 16px;
}
.card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.card h2 {
color: #1e293b;
margin-bottom: 8px;
}
.card .meta {
color: #94a3b8;
font-size: 0.875rem;
margin-bottom: 12px;
}
.tag {
background-color: #eff6ff;
color: #3b82f6;
padding: 2px 8px;
border-radius: 4px;
font-size: 0.75rem;
}
.read-more {
color: #3b82f6;
text-decoration: none;
font-weight: bold;
}
.read-more:hover {
text-decoration: underline;
}
.card:first-child {
border-left: 4px solid #3b82f6;
}
Summary
| Concept | Description |
|---|---|
| Combinator selectors | Target descendants, children, and siblings |
| Pseudo-classes | :hover, :nth-child() β style based on state |
| Pseudo-elements | ::before, ::after β insert generated content |
| Specificity | Priority ranking: ID > Class > Element |
| Cascade | Importance > Specificity > Source order |
| Inheritance | Certain properties pass from parent to child |
Key Takeaways
- Favor class selectors over ID selectors
- Keep specificity as low as possible
- Treat
!importantas a last resort - Know which properties inherit and which do not
Exercises
Exercise 1: Basics
Use nth-child to apply alternating background colors to the rows of a table.
Exercise 2: Applied
Style navigation links with :hover and :focus-visible states. Add a special class for the current page link.
Challenge
Write five CSS rules with different specificity values. Predict which rule wins for a given element, then verify in the browser.
References
Next up: On Day 3, we tackle The Box Model β the foundational concept behind every CSS layout.