Learn CSS in 10 DaysDay 2: Selectors and the Cascade
books.chapter 2Learn CSS in 10 Days

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 &gt; 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: Adding color: 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

  1. Favor class selectors over ID selectors
  2. Keep specificity as low as possible
  3. Treat !important as a last resort
  4. 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.