Day 74: using !important in cascade layers
posted on
It’s time to get me up to speed with modern CSS. There’s so much new in CSS that I know too little about. To change that I’ve started #100DaysOfMoreOrLessModernCSS. Why more or less modern CSS? Because some topics will be about cutting-edge features, while other stuff has been around for quite a while already, but I just have little to no experience with it.
In order to understand how !important
works in cascade layers, you have to understand how !important
works generally. The conclusion of this post might not be what you expect.
The basics
Let's start nice and easy. We have two declarations with the same specificity. The second one wins because it comes later in the document.
h1 {
color: green;
}
h1 {
color: red;
}
I'm red
Adding !important
to the first declaration increases its specificity, turning the color green.
h1 {
color: green !important;
}
h1 {
color: red;
}
I'm green
So far, so good. I assume that most of you already knew that. Now let’s have a look at cascade layers and what happens if we use !important
in layers.
Layers
We have two layers, each with a declaration with the same specificity. The second declaration wins because it’s in a layer defined later in the document.
@layer base {
h1 {
color: green;
}
}
@layer components {
h1 {
color: red;
}
}
I'm red
If we add un-layered styles, the color turns blue because un-layered styles have precedence over layered styles.
h1 {
color: blue;
}
@layer base {
h1 {
color: green;
}
}
@layer components {
h1 {
color: red;
}
}
I'm blue
If we add !important
to the declaration in the base layer, the color turns green.
h1 {
color: blue;
}
@layer base {
h1 {
color: green !important;
}
}
@layer components {
h1 {
color: red;
}
}
I'm green
Okay, I have to stop here for a moment. All this makes sense to me. Here’s what I thought happens before I wrote this blog post:
By default, our order of precedence is like this:
- Un-layered styles (most important)
- components layer
- base layer (least important)
Demo 3 and 4 confirm that.
If we add !important
to the declaration in the base layer, our order looks like this:
- !important base layer (most important)
- Un-layered styles
- components layer
- base layer (least important)
Demo 5 confirms that.
If I keep extending my logic, this would mean that if we add !important
to the components layer, the order looks like this:
- !important components layer (most important)
- !important base layer
- Un-layered styles
- components layer
- base layer(least important)
Let’s try!
h1 {
color: blue;
}
@layer base {
h1 {
color: green !important;
}
}
@layer components {
h1 {
color: red !important;
}
}
I'm green
Nooope, not red, still green. To explain why, let's have a look at the spec.
“CSS attempts to create a balance of power between author and user style sheets. By default, rules in an author’s style sheet override those in a user’s style sheet, which override those in the user-agent’s default style sheet. To balance this, a declaration can be marked important, which increases its weight in the cascade and inverts the order of precedence” (emphasis mine).
CSS Cascading and Inheritance Level 3
This means that !important
doesn't just increase the weight of a declaration in the cascade, but it inverts the order of precedence. So, in our first basic example !important
doesn't just make the first declaration more important, no, it inverts the order of precedence!
h1 {
color: green !important;
}
h1 {
color: red;
}
If we make the first declaration important, this…
- h1 color red (most important)
- h1 color green (least important)
…becomes this:
- h1 color green (most important)
- h1 color red (least important)
Before cascade layers, this didn’t really matter, but now, with multiple layers on the author level, understanding this concept is critical. If we apply this logic to our last layer example, we get this:
- !important base layer (most important)
- !important components layer
- !important un-layered styles
- Un-layered styles
- components layer
- base layer(least important)
So, even if we add !important
to the un-layered styles, the declaration in the base layer still wins.
h1 {
color: blue !important;
}
@layer base {
h1 {
color: green !important;
}
}
@layer components {
h1 {
color: red !important;
}
}
I'm still green
Got it? No? Don't worry. It took me more than an hour to understand it. This video by Una Kravets helped a lot:
Further reading
- Day 37: cascade layers
- Day 40: unlayered styles
- Day 43: grouping layers
- Day 46: ordering layers
- Day 49: layering entire style sheets
- Day 52: multiple layer lists
- Day 55: anonymous layers
- Day 58: ordering nested layers
- Day 64: the revert-layer keyword
- Day 68: cascade layers and browser support
- !important on MDN
Overview: 100 Days Of More Or Less Modern CSS