Topic 2.1
The Cascade
In one line
When several declarations try to set the same property on the same element, the cascade picks exactly one winner by comparing, in order: origin and importance, inline style, cascade layer, specificity, and order of appearance.
Think of it like this
Three people tell you what to wear today. Your school's rule says "uniform", your parent says "take a jacket", your friend says "wear the red cap". You don't wear everything at once: for each item (shirt, jacket, cap) you follow a fixed order of who to listen to first. The cascade is the browser's fixed order of who to listen to, applied to each property (colour, size, margin…) of each element separately.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Declaration
- One
property: valuepair, likecolor: red;. - Competing declarations
- Several declarations that try to set the same property on the same element.
- Cascade
- The browser's fixed set of steps for choosing one winner among competing declarations.
- Origin
- Where a style came from: the browser's defaults (user-agent), the person browsing (user), or the website (author).
- User-agent stylesheet
- The browser's built-in default styles, like blue underlined links and big bold headings.
- Inline style
- CSS written in an element's
styleattribute:<p style="color: red">. - Specificity
- A score for how precisely a selector points at an element. More precise selectors win ties.
- Order of appearance
- Where a declaration sits in the page. When everything else ties, the later one wins.
- Cascaded value
- The single value the cascade picked for one property of one element.
Step by step
01Collect every declaration that matches
Take one element, say a paragraph with class="note" and id="tip", and one property, color. The browser gathers every declaration for color whose selector matches this paragraph, from every stylesheet, plus any style attribute.
Here three rules match. Without the cascade, the browser couldn't decide which colour to paint.
#tip { color: crimson; }
.note { color: seagreen; }
p { color: steelblue; }02Compare origin and importance
All three come from the author origin (your stylesheet) and none uses !important, so they tie at this step. A declaration from the browser's default stylesheet (for example the blue colour of links) would already have lost here, because normal author styles beat normal user-agent styles.
03Check for inline styles and layers
None of the three is in a style attribute, and none is inside an @layer block, so they tie again. If the paragraph had style="color: purple", purple would win right here, and specificity would never be looked at.
04Compare specificity
Now the selectors are compared. #tip contains an ID, .note a class, p only a type. The ID selector is the most specific, so color: crimson wins, even though it is written first in the file.
That surprises many beginners: order only decides when specificity ties.
05If still tied, the last one wins
If two rules had the same specificity, say two .note rules, the one written later would win. The browser reads the page from top to bottom, and the later declaration overrides the earlier one.
.note { color: gray; }
.note { color: navy; } /* same specificity, later: navy wins */06No declaration at all? Defaulting
If no declaration sets the property, there is nothing to choose. The browser then defaults the value: inherited properties such as color copy the parent's value, and the rest (such as border) use their initial value. You'll learn this in Topic 2.3.
Try it yourself
- 1
Predict, then move a rule
In the first example, predict what happens if you move the
#tiprule to the very end of the CSS. Write your guess down, then try it. (Paragraph 1 stays crimson: specificity is checked before order.) - 2
Make two rules tie
In the first example, change
#tipto.noteso there are two.noterules. Predict the colour of the first two paragraphs before you run it. Now the later rule wins. - 3
Find the loser in DevTools
Right-click paragraph 2 of the second example's preview and choose Inspect. In the Styles pane, the
.msg { color: gray }declaration is crossed out: that's DevTools telling you it lost the cascade. The winning rule is listed above it.
Code & diagrams
Every paragraph is bold: the `font-weight` rule had no competitor. The colour battle is decided by specificity, not by order. `getComputedStyle` reports colours as `rgb(...)` and bold as `700`.
Preview
Console
Nothing logged yet.Expected console output
Paragraph 1: crimson 700
Paragraph 2: seagreen 700
Paragraph 3: steelblue 700The CSS tab is placed in the page's head, and the `<style>` element in the HTML tab comes later in the document, so its `.late` rule wins the tie.
Preview
Console
Nothing logged yet.Expected console output
Link: darkorange
Paragraph 1: navy
Paragraph 2: purple
Paragraph 3: seagreen
Paragraph 4: tomatoBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
A rule that seems to do nothing
In the first example, add p { color: black; } at the end of the CSS and expect every paragraph to turn black.
Break #2
Swap the stylesheet links
In a real page, load your own style.css before a library's stylesheet: <link rel="stylesheet" href="style.css"> then <link rel="stylesheet" href="library.css">.
Myth vs fact
Myth
The last rule in the file always wins.
Fact
Order is the last step of the cascade. Origin and importance, inline styles, layers and specificity are all checked first.
Myth
"Cascading" means styles flow down from parents to children.
Fact
That is inheritance, a separate mechanism. The cascade picks a winner among competing declarations on one element. The two work together, but they are different steps.
Myth
A whole rule wins or loses.
Fact
The cascade runs per property. One rule can win color and lose font-size on the same element.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
The full order in the CSS Cascading and Inheritance Level 5 specification, from strongest to weakest origin and importance: transitions, important user-agent, important user, important author, animations, normal author, normal user, normal user-agent. So a running CSS animation overrides your normal rules but not your
!importantones, and a transition beats everything while it runs. - ▸
Spec details for the steps after origin: context (inside Shadow DOM, styles from the outer page beat the component's normal styles, and the order flips for
!important), then element-attached styles (thestyleattribute), then layers, then specificity, then order of appearance. The newest draft (Level 6) adds scope proximity for@scopebetween specificity and order: the rule whose scope root is closer to the element wins. - ▸
Rules inside
@mediaor@supportsblocks have no extra weight. They take part in the cascade exactly like rules outside them, at the position they are written. A media query at the top of the file can lose to a plain rule further down. This is a classic responsive-design bug (Phase 9). - ▸
The cascade produces the cascaded value. The browser then turns it into the specified, computed, used and finally actual value (for example
2embecomes32px).getComputedStyle()in JavaScript returns the resolved value, which is the computed value for most properties and the used value for some, likewidth.
Remember this
- 1
A declaration is one
property: valuepair, likecolor: red. Many declarations can target the same element and the same property: a browser default, your stylesheet, a class rule, an ID rule, astyleattribute. For every element and every property, the browser collects all those competing declarations and must choose exactly one. The chosen value is called the cascaded value. The process of choosing is the cascade. - 2
Step 1 is origin and importance. An origin is where a style came from: the user-agent origin (the browser's own default stylesheet: blue links, bold headings, margins on
body), the user origin (styles the person browsing set up, such as a minimum font size or a high-contrast extension) and the author origin (you, the website's developer). For normal declarations, author beats user, and user beats user-agent. Declarations marked!importantflip that order (Topic 2.4 explains why). - 3
Step 2: a declaration in an element's
style="..."attribute (an inline style) beats any declaration that comes from a selector in a stylesheet, as long as origin and importance are equal. Step 3 is cascade layers: rules placed in named layers with@layerare ranked by layer order, and rules in no layer at all beat every layered rule (Topic 2.5). - 4
Step 4 is specificity: a score for how precisely a selector targets the element. An ID selector (
#tip) beats a class (.note), which beats a type selector (p). Specificity only matters when the earlier steps tie. Topic 2.2 shows how to score any selector. - 5
Step 5 is order of appearance: if everything above ties, the declaration that appears last in the page wins. "Last" means later in the same stylesheet, or in a stylesheet that comes later in the document (a later
<link>or<style>). This is why the order of your<link>tags matters, as you saw in Topic 0.2. - 6
The cascade runs per property, not per rule. If one rule wins the
colorbattle and another winsfont-size, the element ends up with a mix of both. And if no declaration sets a property at all, the cascade has no winner: the browser then uses inheritance (the parent's value, for properties likecolor) or the property's initial value (its built-in default). That's Topic 2.3.
Explain it without notes
Name the steps of the cascade in order, and say what each one compares.
What is an origin? Name the three origins and how they rank for normal declarations.
A rule #box { color: red } is written at the top of a file and .box { color: blue } at the bottom. Both match the same element. Which colour wins and why?
What happens to a property that no declaration sets?
Practice
Write CSS for <p class="intro">Hello</p> with two rules for .intro: the first sets color: red, the second color: green. Which colour shows? Then make red win without !important and without changing the HTML.
Given the HTML <h1 class="title">Hi</h1> and the rules h1 { color: navy; font-size: 40px; } and .title { color: tomato; }, what colour and size does the heading get?
Trade-offs
- ↔
Relying on order of appearance keeps selectors short, but makes styles fragile: moving a file or a
<link>changes the result. Relying on specificity is independent of order, but raises the bar for every later override. Cascade layers (Topic 2.5) give an explicit, order-independent way to rank whole groups of rules.
Done when you can
I can list the five steps of the cascade in order.
I can name the three origins and say how they rank.
I can predict which of several rules sets a property on an element.
I know the cascade works per property, not per rule.
I can find the winning and losing declarations in DevTools' Styles pane.