CSS Selectors and the Cascade
Learn how CSS selectors target elements, and how specificity and the cascade decide which rule wins when several match.
What you'll learn
- Write type, class, id, and descendant selectors
- Predict which rule wins when multiple selectors match the same element (specificity)
- Explain how inheritance passes some CSS properties from parent to child
Prerequisites
Explanation
CSS stands for Cascading Style Sheets, and that first word is doing real work: when several rules could apply to the same element, the browser doesn't pick one at random or just use whichever you wrote most recently — it follows a precise, learnable algorithm called the cascade.
Selectors: Choosing What to Style
A selector is the part of a rule before the curly braces, and it decides which elements the rule applies to:
- A type selector, like
porh1, matches every element of that kind. - A class selector, like
.warning, matches every element carryingclass="warning"— an element can have several classes at once, separated by spaces. - An id selector, like
#header, matches the single element withid="header"(ids should be unique per page). - A descendant selector, like
nav a, matches any<a>nested anywhere inside a<nav>, no matter how deeply.
Classes are the workhorse of everyday CSS — reusable across as many elements as you like — while ids are better reserved for unique page landmarks or JavaScript hooks than for everyday styling.
Specificity: Who Wins?
When two rules with different selectors both match the same element, CSS uses specificity to rank them. From lowest to highest:
- Type selectors (
p) and pseudo-elements — the least specific. - Class selectors (
.warning), attribute selectors, and pseudo-classes. - Id selectors (
#header) — more specific than any number of classes. - Inline
style="..."attributes, and!important, which override almost everything and should be used sparingly, if ever.
A more specific selector wins regardless of where it's written in the file. Only when two selectors tie in specificity does source order become the tiebreaker — the rule that appears later in the stylesheet wins.
The Cascade in Practice
This is why a class selector can feel like it "loses" to an id selector even if the class rule is written last: specificity, not position, decides first. It's also why relying on !important to force a rule to win tends to backfire later — it makes the next override even harder to write cleanly, since now you need something even stronger to beat it.
Inheritance
Separately from the cascade, some CSS properties inherit from parent to child automatically, without any selector targeting the child at all. Text-related properties like color, font-family, and font-size inherit — set them once on <body>, and every nested paragraph and heading picks them up unless overridden. Box-model properties like margin, padding, border, and width do not inherit — a parent's border does not appear around its children.
Put together: selectors decide what a rule targets, specificity plus source order decide which rule wins when several match, and inheritance quietly hands a small set of text properties down the tree for free. Once these three ideas click, CSS output stops feeling mysterious.
Example
A page showing type, class, and id selectors competing for the same paragraphs, demonstrating specificity.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Selectors and cascade</title>
<style>
body {
color: black;
font-family: sans-serif;
}
p {
color: blue;
}
.warning {
color: orange;
}
#critical {
color: red;
}
</style>
</head>
<body>
<p>Plain paragraph: styled blue by the type selector.</p>
<p class="warning">Warning paragraph: the class selector beats the type selector, so this is orange.</p>
<p id="critical" class="warning">Critical paragraph: even with the "warning" class, the id selector wins, so this is red.</p>
</body>
</html>Try it yourself
Add a new .success rule with color: green, add class="success" to a paragraph, then press Run.
Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.
Guided exercise
Guided exercise
Add a class selector rule .highlight { color: green; } inside the <style> block so the paragraph with class="highlight" turns green, without touching the existing p rule.
Checks: The .highlight paragraph renders green · plus 1 hidden check
Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.
Stuck? Get a hint.
Independent exercise
Independent exercise
Inside the <style> block, write three rules so that: all paragraphs are blue by default (type selector), paragraphs with class "note" are orange (class selector), and the paragraph with id="urgent" is red even though it also has class="note" (id selector beats class selector).
Checks: Paragraph A is blue · Paragraph B is orange · plus 1 hidden check
Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.
Stuck? Get a hint.
Common mistakes
- Assuming the last rule in the file always wins — that's only true when competing selectors have equal specificity; a more specific selector wins regardless of order.
- Overusing #id selectors for everyday styling, which makes rules hard to reuse or override later — classes are usually the better default.
- Forgetting that properties like color and font-family inherit from parent to child, while box-model properties like margin and border do not.
- Reaching for !important to win a specificity fight instead of fixing the underlying selector, which makes future overrides much harder to write.
Knowledge check
Takeaway
When several CSS rules could apply, the browser doesn't guess — it follows a precise specificity and source-order algorithm you can predict every time.
Summary
CSS selectors — type, class, id, and descendant — decide which elements a rule targets. When multiple rules match, specificity (id beats class beats type) decides the winner, with source order only as a tiebreaker between equally specific rules. Text properties like color inherit from parent to child automatically; box-model properties do not.
References
Your notes
Notes save automatically.
Finished this lesson?
Mark it complete to track your progress and schedule a future review.
AI tutor
The optional AI tutor isn't enabled in this deployment. All lessons, exercises, quizzes, and search work fully without it.