Knownow
Knownow

Reputation: 385

CSS specificity and !important

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

Answers (1)

zer00ne
zer00ne

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:

  1. Find an <aside> tag with the class of .inner3
  2. It must have a parent <div> that has the class of .inner2.
  3. Also that <div class="inner2">must have a parent <div> with a class of .inner1.
  4. And it's imperative that <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.


Demo


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

Related Questions