CSS Specificity, Cascade and Inheritance
When two CSS rules try to style the same element, the browser needs a way to choose the winner. This chapter explains how it decides.
The Cascade in Simple Words
"Cascading" means the rules flow down like water, and the browser sorts them before using them. It looks at these things, in this order:
- Importance: is the declaration marked
!important? - Origin and layers: browser styles, your styles, inline styles (and cascade layers, which you will meet later)
- Specificity: how exact is the selector?
- Source order: if everything else is equal, the rule written last wins
Most of the time, the fight is decided by specificity or by source order.
Source Order
If two selectors are equally strong, the later one wins.
Example
p { color: blue; }
p { color: green; }Every paragraph is green, because the second rule comes later.
What is Specificity?
Specificity is a score for each selector. You can think of it as three columns: A-B-C.
| Column | Counts | Example |
|---|---|---|
| A | ID selectors | #menu |
| B | Classes, attributes and pseudo-classes | .active, [type="text"], :hover |
| C | Element names and pseudo-elements | p, li, ::before |
The browser compares column A first. Only if A is the same does it look at B, then C. So one id beats any number of classes.
| Selector | Score (A-B-C) |
|---|---|
p | 0-0-1 |
ul li | 0-0-2 |
.price | 0-1-0 |
p.price | 0-1-1 |
.card .price | 0-2-0 |
#cart .price | 1-1-0 |
The universal selector * and combinators like >, + and the space count as zero.
See It in Action
Guess the colour of the price before you run the example.
Example
<!DOCTYPE html>
<html>
<head>
<style>
#cart .price { color: crimson; }
.card .price { color: green; }
p.price { color: orange; }
p { color: gray; }
</style>
</head>
<body>
<div id="cart">
<div class="card">
<p class="price">Rs 2,750</p>
</div>
</div>
</body>
</html>Try it Yourself »The price is crimson. #cart .price has an id, so its score (1-1-0) beats all the others, even though it is written first.
Inline Styles and !important
A style attribute on the element is stronger than any selector in a stylesheet.
!important after a value jumps over normal specificity:
Example
.note {
color: navy !important;
}Use !important only as a last resort, for example to override a third-party library. If you use it a lot, your CSS becomes very hard to fix later, because the only way to beat !important is another !important.
Inheritance
Some properties pass down from a parent to its children automatically. This is called inheritance. If you set color on <body>, all text inside gets that colour, unless something else overrides it.
| Usually inherited | Usually not inherited |
|---|---|
color | margin, padding |
font-family, font-size | border |
line-height, text-align | background |
visibility, cursor | width, height |
Example
<!DOCTYPE html>
<html>
<head>
<style>
.box {
color: #264de4;
font-family: Georgia, serif;
border: 2px solid #264de4;
padding: 12px;
}
</style>
</head>
<body>
<div class="box">
<h3>Ayesha's Bakery</h3>
<p>Fresh cakes every morning in Gulshan.</p>
</div>
</body>
</html>Try it Yourself »The heading and paragraph get the blue colour and the Georgia font from the box. They do not get their own border, because border is not inherited.
An inherited value is always weaker than a rule that targets the element directly. Even a plain p { color: black; } beats a colour inherited from the parent.
Controlling Inheritance
You can tell a property exactly what to do with these keywords. They work on every property.
| Keyword | Meaning |
|---|---|
inherit | Take the parent's value |
initial | Use the default value from the CSS rules |
unset | Inherit if the property normally inherits, otherwise use initial |
revert | Go back to the browser's own default style |
Example
button {
font: inherit; /* buttons use the page font instead of the system font */
}
a.plain {
color: inherit; /* the link takes the colour of the text around it */
}Tips for Fewer Fights
- Style mostly with single classes, so scores stay low and equal
- Avoid ids in your CSS selectors
- Avoid long chains like
div.main ul li a - Put general rules first and specific ones later
Exercise
Exercise
Which selector has the highest specificity?
