How do CSS rules take precedence?

Asked

Viewed 1,619 times

12

I know that if two CSS rules apply to the same element, the more specific one will have priority:

p { color:red; }             /* Todos os "p"s serão vermelhos... */
.umaClasse { color:yellow; } /* ...exceto os que possuem "umaClasse", que serão amarelos */
#umID { color:green; }       /* ...exceto o "umID", que será verde. */

And intuitively I realize that "the element with the X ID" is more specific than "all elements with the Y class". In the case of class, ok, there may be more elements with class Y than elements with tag Z (if the same class applies to several different tags), but anyway as it is something defined by the programmer I understand that it should have priority.

I also know that if two "equal" rules exist (i.e. with the same selector), which has been defined afterward will take priority. And recently while trying answer another question my tests have shown that the same applies to media queries (i.e. if there are two equally applicable rules, the one that appeared after).

My confusion starts in cases where there is more than one criterion on the same selector (type p.umaClasse) - which I imagine only increases its specificity (i.e. has to have the tag p and the class umaClasse). On the other hand, I see no difference between p#umID or simply #umID, since there is only one element with this ID, both selectors should be equal, but it turns out that the first one has priority:

p#a { color: blue; }
#a { color: red; }
<p id="a">Teste</p>

Another confusing situation is when selecting one element within the other:

.a div p span { color:red; }
div .d { color:green; }
.b .c span { color:blue; }
<div class="a">
  <div class="b">
      <p class="c">
        <span class="d">Teste</span>
      </p>
  </div>
</div>

I noticed that the last rule took precedence and, if commented, the first rule will take precedence. Why?

  • If we did an analysis top-down, the first should be the most specific (because the second and third would take descendants of any element, not only the divs with class a);
  • If we did an analysis bottom-up, the second should be the most specific (because the first and third take any span, and second only to those with the class d);
  • The first has a longer chain, but the third establishes more classes. Is this the dominant factor? And if we mixed classes with ids, how would it look?

I also tried to think of an example with pseudo-classes or attributes, but it has confused my head even more...

There is a simple way to determine, among two CSS rules, which one will have priority? Whether the hierarchy of elements is taken into account or not, etc.

  • There is a very complicated question. There are many rules... +1

  • In the latter example the precedence seems to have been determined by the calculation of specificity ("Specificity Calculations"): http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/

  • 1

    I just thought the abc confuses a little, because to see p#a thinking about <a>.

  • 1

    @brasofilo As soon as possible, I edit to use xyz instead (hadn’t noticed that detail, thanks!)

  • Upsie... already has an answer referencing abc...

2 answers

11


The rule to define which will be considered the most specific, calculates, shall we say, the heaviness of each selector. For this, 4 values are used, they are:

A = will be 1 if the style is present in an inline style, otherwise 0
B = number of selectors of the ID attribute
C = number of attribute selectors, classes and pseudo-classes
D = number of element selectors and pseudo-elements

So, by counting the selectors, we have in your css as an example:

.a div p span { color:red; }  --A=0 B=0 C=1 D=3
div .d { color:green; }       --A=0 B=0 C=1 D=1
.b .c span { color:blue; }    --A=0 B=0 C=2 D=1

The highest value is used in order following the rule that A > B > C > D. In the case of this example in the last rule, we have C=2 and therefore it takes precedence over the first.

You can read about it in css specifications on the W3C website

  • Further reference for a detailed explanation: http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/

0

One way to go up in precedence is to add ! Important to the end of the attribute.

ex:

th.td_student{
  background-color: #000 !important;
}

Here was needing to overwrite a color statement declared in inline style by a plugin.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.