CSS Override Rules and Specificity

CSS override rules and specificity

To give the second rule higher specificity you can always use parts of the first rule. In this case I would add table.rule1 trfrom rule one and add it to rule two.

table.rule1 tr td {
background-color: #ff0000;
}

table.rule1 tr td.rule2 {
background-color: #ffff00;
}

After a while I find this gets natural, but I know some people disagree. For those people I would suggest looking into LESS or SASS.

Why does an earlier CSS rule override a later rule?

You should read about CSS specificity.

.four-across li is more specific than .no-search-results, so it have higher importance level.

Specificity is calculated by counting various components of your css
and expressing them in a form (a,b,c,d). This will be clearer with an
example, but first the components.

  • Element, Pseudo Element: d = 1 – (0,0,0,1)
  • Class, Pseudo class, Attribute: c = 1 – (0,0,1,0)
  • Id: b = 1 – (0,1,0,0)
  • Inline Style: a = 1 – (1,0,0,0)

by Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade

Document order matters only when given specificity is exactly the same. In you example first selector is (0,0,1,1) and second is (0,0,1,0), so the first one overrides the second one, no matter how are they ordered within CSS document.

How does a CSS rule override another CSS rule?

Because of CSS Specificity. A selector's weighting is evaluated based on the components that make it up, with id's given a weighting of 100, classes with a weighting of 10, and element selectors with weighting of 1.

So in your example:

table#id-form td

Has a weighting of 102 (table#id is 101 and td is 1), whereas this:

#particular-td

Has a weighting of 100. If you change your second to this:

#id-form #particular-td

You will get a weighting of 200 which will override the previous selector. Only as a last resort should you ever use !important, as this pretty much prevents you from overriding it further down the line.

CSS lower specificity rules override higher specificity rules

The selectors .parent-class p and p.child-class have exactly the same CSS specificity, both have 1 tag selector and 1 class selector. The selector that comes later in code will apply.

Why are my CSS properties being overridden/ignored?

Elements id have the priority in CSS since they are the most specific.
You just have to use the id:

#content li.post-item > * {
margin: 0px;
}

#content .item-description {
color: #FFF;
}

#content .item-meta {
color: #666;
}

Basically id have the priority on class which the priority on tags(p,li,ul, h1...). To override the rule, just make sure you have the priority ;)

How to override !important?

Overriding the !important modifier

  1. Simply add another CSS rule with !important, and give the selector a higher specificity (adding an additional tag, id or class to the selector)
  2. add a CSS rule with the same selector at a later point than the existing one (in a tie, the last one defined wins).

Some examples with a higher specificity (first is highest/overrides, third is lowest):

table td    {height: 50px !important;}
.myTable td {height: 50px !important;}
#myTable td {height: 50px !important;}

Or add the same selector after the existing one:

td {height: 50px !important;}

Disclaimer:

It's almost never a good idea to use !important. This is bad engineering by the creators of the WordPress template. In viral fashion, it forces users of the template to add their own !important modifiers to override it, and it limits the options for overriding it via JavaScript.

But, it's useful to know how to override it, if you sometimes have to.

More important than !important (a higher level !important)?

No, there is no keyword or other way to make a declaration more important than !important. There is no known activity to change this.

In general, it is possible to override a declaration that has !important by using a rule that also has it and that has higher specificity. However, a declaration in a style attribute has, by definition, higher specificity than any other author declaration. The only way to defeat it is in CSS is to use a user style sheet with !important.

There are non-CSS solutions, but they are rather obvious, such as using JavaScript to simply remove or modify the style attribute.

CSS specificity and !important

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>

My selector has maximum specificity but still isn't being applied. Why not?

Try to verify that your code is placed lower in the compiled file. Otherwise try to strengthen the weight of your selector by an id (for example):

#parentContainer{ 
.post-item, .post-type-project, .project, .type-project {
.post-text {
width: calc(35% - 15px);
}
}
}


Related Topics



Leave a reply



Submit