Reputation: 385
I think I have a wrong understanding of how specificity and !important works .
Consider the below HTML :
<head>
<link href="css/style.css" rel="stylesheet">
<link href="css/style1.css" rel="stylesheet">
</head>
<body>
<div class = "outer">
<div class = "inner1">
<div class = "inner2">
<p>Voluptate labore cupidatat an enim quamquam ut anim malis, varias id sed veniam
quibusdam, singulis aliqua ut singulis domesticarum, id aliqua illum o officia,
et ab domesticarum, irure e excepteur o eram nam appellat coniunctione do
commodo..</p>
</div>
</div>
</div>
STYLE.CSS
.outer .inner1 {
color:green !important;
}
STYLE1.CSS
.outer .inner1 .inner2 {
color:red ;
}
My understanding was the rule in style.css will never be overwritten (as it has an important tag) even though the rule in syle1.css has more specificity . I was thinking rules are applied as they are encountered in the HTML file ( style.css first and then style1.css) , and a value for a particular property of an element will be overwritten only if the rule is more specific ( important tag prevents this overriding no matter how specific the subsequent rule is ) . This apparently is not how it works . Could someone tell me how does !important and specificity work and when do you use !important ?
Upvotes: 2
Views: 1561
Reputation: 44108
Styles for a directly targeted element will always take precedence over inherited styles, regardless of the specificity of the inherited rule.
-- Specificity: Directly targeted elements vs. inherited styles
Note: the addition of the new contrived ruleset in Demo:
div.outer.outer.outer>div.inner1>div.inner2.inner2>aside.inner3 {
color: blue !important
}
It has an incredibly ridiculously unnecessarily huge specificity score of 0,0,7,4 and !important as well. CSS reads from right to left:
<aside>
tag with the class of .inner3
<div>
that has the class of .inner2
.<div class="inner2">
must have a parent <div>
with a class of .inner1
.<div class="inner1">
have a parent <div>
with the class of .outer
.All of these specific rules of the selector must be met just so a deeply nested <aside>
tag gets its style. Any descendant elements of .inner3
will inherit color: blue
property and value, but it is easily overridden by the likes of i.inner2
with color:red
.
<div class="inner3">
<p>This deeply nested text has <i class='inner2'>crazy specificity but this text is red.</i>
...
</p>
</div>
Note: the new ruleset at the bottom of CSS box:
div {
color: black !important
}
Now this selector is specific to all divs so here is how !important
has just been assigned a selector with a far reaching scope. This is probably more like the behavior you were expecting.
BTW, you probably noticed the duplicate classes:
.outer.outer.outer
That is called selector chaining which will increase a selector's specificity score. See Online Specificity Calculator.
div.outer.outer.outer>div.inner1>div.inner2.inner2>aside.inner3 {
color: blue !important
}
.outer .inner1 {
color: green !important;
}
.outer .inner1 .inner2 {
color: red;
}
div {
color:black !important;
}
<head>
<link href="css/style.css" rel="stylesheet">
<link href="css/style1.css" rel="stylesheet">
</head>
<body>
<div class="outer">
<div class="inner1">
This text will be green...
<div class="inner2">
<p>Voluptate labore cupidatat an enim quamquam ut anim malis, varias id sed veniam quibusdam, singulis aliqua ut singulis domesticarum, id aliqua illum o officia, et ab domesticarum, irure e excepteur o eram nam appellat coniunctione do commodo..
</p>
<aside class='inner3'>
<p>This deeply nested text has <i class='inner1'>crazy specificity</i>, yet it only applies to it and its descendants with no specific <b class='inner2'>`color` property</b>.</p>
</aside>
</div>
...and this text will be green as well.
</div>
</div>
Upvotes: 2