Learn
03.2 | THE CASCADE, SPECIFICITY AND INHERITANCE
01 | WHY DOES MY COLOUR NOT CHANGE?
You give a paragraph a green colour, but it stays purple. There may be several declarations applying to the same element. CSS needs a consistent way to decide which one supplies each property.
The cascade is the process that resolves competing declarations. It considers factors including origin, importance, cascade layers, specificity and order. In this lesson, most examples use ordinary, unlayered author CSS with no animations or transitions.
That scope matters: “the most specific selector wins” is only a useful rule once higher-priority cascade factors are equal. The last rule does not always win.
02 | RESOLVE EACH PROPERTY SEPARATELY
<p class="notice">Next meeting: Friday.</p>p {
color: green;
line-height: 1.6;
}
.notice {
color: purple;
padding: 12px;
}Both selectors match. For ordinary declarations here, .notice has greater specificity than p, so the text becomes purple. The paragraph still receives line-height: 1.6 and padding: 12px.
A winning colour declaration does not erase every other rule. The cascade resolves each property individually. Only declarations competing for the same property need a winner.
03 | COMPARE SPECIFICITY AS THREE COUNTS
p /* 0, 0, 1 */
.notice /* 0, 1, 0 */
p.notice /* 0, 1, 1 */
.card .notice /* 0, 2, 0 */
#announcement /* 1, 0, 0 */For these basic selectors, compare a tuple of counts: IDs, classes/attributes/pseudo-classes, then element types/pseudo-elements.
- Compare ID counts first.
- If equal, compare the middle count.
- If still equal, compare the final count.
Compare from left to right; do not add the counts into one ordinary number. In this group, #announcement outranks .card .notice, even though the latter has two classes.
Spaces and combinators do not add specificity. The universal selector * adds none. More advanced selectors have special rules, which you can explore later.
04 | SOURCE ORDER BREAKS A TIE
.notice {
color: green;
}
.notice {
color: purple;
}Both declarations have the same origin, importance, layer and specificity. The later declaration wins, so the colour is purple.
#announcement { color: green; }
.notice { color: purple; }If a paragraph has both id="announcement" and class="notice", the ID selector wins in this ordinary example even though the class rule appears later.
Internal CSS and external CSS do not get different priority simply because of where they are stored. For tied declarations, their effective order in the document and stylesheets matters.
05 | INLINE STYLES AND IMPORTANT
<p class="notice" style="color: green;">Meeting reminder</p>.notice {
color: purple;
}An ordinary inline style takes precedence over normal author stylesheet declarations for that element. Here, green wins.
.notice {
color: purple !important;
}An important author declaration outranks a normal inline declaration for the same property, so this changes the result to purple. !important is a declaration flag, not extra selector specificity.
Do not use !important as your first repair. Inspect the cause and simplify competing rules where possible. Important declarations have their own ordering rules, and user-important styles can override author-important styles.
The full cascade also accounts for user and browser styles, layers, animations and transitions. These examples deliberately keep those factors simple.
06 | INHERITANCE PASSES SOME VALUES DOWN
<section class="club-info">
<h2>Robotics Club</h2>
<p>We build and test ideas.</p>
</section>.club-info {
color: #24988f;
font-family: Arial, sans-serif;
border: 2px solid #24988f;
}With no other declarations setting their colour or font, the heading and paragraph inherit those properties from the section.
Not every property is inherited. Borders, margins and padding normally are not. The section has a border, but its children do not automatically get their own borders.
Colour and many font properties normally inherit. A transparent background may let the parent’s background show through; that is not the same as inheriting background-color.
07 | A DIRECT VALUE BEATS AN INHERITED VALUE
.club-info { color: green; }
p { color: purple; }A paragraph inside .club-info becomes purple because a declaration directly sets its colour. The class selector on the parent does not compete against p as though both selected the paragraph.
This is an important distinction: specificity is compared between competing declarations on the same element. Inheritance supplies a value when the child does not get one directly through the relevant value-resolution rules.
p { color: inherit; }inherit explicitly requests the parent’s computed value for that property. It can also be used on properties that do not normally inherit.
initial requests the property’s specification-defined initial value, which is not necessarily the browser’s usual styling for that element. unset behaves like inherit for normally inherited properties and like initial for the others.
08 | TRY IT: COMPETING COLOURS
Choose a scenario and predict the winning colour. Each demonstration runs in a separate frame so its CSS cannot restyle this lesson.
Choose a scenario, predict the result, then select Show the result.
09 | DEBUG THE CAUSE, NOT JUST THE SYMPTOM
- Inspect the element and the property that looks wrong.
- Confirm which selectors match that element.
- Look for important or inline declarations and other cascade factors.
- Compare specificity where those factors are equal.
- Use source order only when earlier comparisons tie.
- Check whether the value is inherited from a parent.
Browser developer tools often show overridden declarations crossed out and identify inherited values. Computed styles help you see the resolved result.
Keep selectors as simple as your design allows. Reusable classes usually make styles easier to maintain than a growing chain of IDs and important overrides.