:nth-of-type selector overrides all other CSS selectors
Asked Answered
K

4

7

I am trying to revise for my exam on HTML, JavaScript and CSS3; and I am a little confused at CSS selectors and which take priority.

I have the following CSS:

table                   { border: 1px solid black; }
tr:nth-child(odd)       { background-color: red; }
tr td:nth-of-type(even) { background-color: blue; }
td                      { background-color: green; }

I thought that whatever comes last takes priority, so in my opinion all cells in the table would be green.

However the even cells are still blue, as per the nth-of-type selector. Even when I put this to the top and remove the green td line, the blue is still shown in the middle with only the odd cells showing in red.

Can someone explain why the nth-of-type seems to take precedent over everything else?

Here is the example:

table { border: 1px solid black; }
tr:nth-child(odd) { background-color: red; }
tr td:nth-of-type(even) { background-color: blue; }
td { background-color: green; }
<table style="width: 100%;">
  <tr>
    <td>Jill</td>
    <td>Smith</td>
    <td>50</td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
  <tr>
    <td>John</td>
    <td>Doe</td>
    <td>80</td>
  </tr>
  <tr>
    <td>John</td>
    <td>Doe</td>
    <td>80</td>
  </tr>
</table>

https://jsfiddle.net/e6157xwz/

Klopstock answered 15/6, 2015 at 19:47 Comment(1)
Well I think you have your answer with regards to specificity being the issue here. This also why you typically see experienced CSS developers, placing more specific rules within one specific section of CSS after more general rules. It makes the intended behavior of what you are writing more clear.Peshawar
A
4

The rule with the blue is more specific and that is why it takes precedence.

Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity

Actinotherapy answered 15/6, 2015 at 19:49 Comment(1)
The w3 spec is here: http://www.w3.org/TR/selectors/#specificityCarmelocarmen
B
7

So what's this?

What's going on here is selector specificity.

The following list of selector types is by increasing specificity:

  1. Universal selectors (e.g. *)
  2. Type selectors (e.g. h1)
    Class selectors (e.g. .example)
    Attribute selectors (e.g. [type="radio"])
  3. Pseudo-classes (e.g., :hover)
  4. ID selectors (e.g. #example)
  5. Inline style (e.g. style="font-weight:bold")

Simplified explanation for your code

In your example, the pseudo selector :nth-of-type(even/odd) is category 3 which takes precedence since the concurring selectors are only type selectors (category 2.1).

Important note

Deviating from MDN information available behind that link, I have corrected that type, class and attribute selectors actually have the same specificity.

Bastinado answered 15/6, 2015 at 19:54 Comment(5)
So how in this example would I get red rows, but then blue only in the even columns of the even rows?Klopstock
Actually I think I have worked it out: tr:nth-of-type(even) td:nth-of-type(even) { background-color: blue; }, is that correct?Klopstock
Your CSS is at least confusing. Please describe in detail what exactly you want to achieve.Bastinado
@Klopstock the examples on w3.org/TR/css3-selectors/#specificity explain this in more detail.Heifetz
Until MDN fixes its specificity list please refrain from quoting that article. It implies that classes, attributes and pseudo-classes have different specificity values, which they do not. As others have mentioned the spec is much more accurate, it being the authoritative resource, even if it's less accessible.Emera
A
4

The rule with the blue is more specific and that is why it takes precedence.

Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity

Actinotherapy answered 15/6, 2015 at 19:49 Comment(1)
The w3 spec is here: http://www.w3.org/TR/selectors/#specificityCarmelocarmen
S
2

This is not related to order, but to accuracy. The first selector is one selector of a type, the second selector is a selector of type and then specifies a filter while the third specifies two types and a filter.

The more accurate the selector, the more priority. Declaring order only matters when two (or more) selectors are evenly accurate.

Saccharoid answered 15/6, 2015 at 19:50 Comment(2)
Thank you very much, this now makes a lot more sense.Klopstock
Typically this is referred to as specificity, not accuracy.Peshawar
H
2

This is because of the specificity of your selectors. There are two rules that match td elements. Their calculated specificity is:

tr td:nth-of-type(even) -> 0,0,1,2
td                      -> 0,0,0,1

The rule with higher specificity wins regardless of source order.

Heifetz answered 15/6, 2015 at 19:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.