0

I think I get CSS specificity, but this particular case is throwing me:

li:first-child {color:  blue}                /* 3 */
div li {color:  red}                         /* 5 [R2] */
div.widget  ul#todo {color:  cyan}           /* 1 [R3] */

div > ul#todo .important {color:  green}     /* 1 */
ul li.postponed {color:  inherit}            /* 2 */
li + li + li {color:  magenta}               /* 4 */
<div  class="widget">
    <ul id="todo">
       <li>Buy  Bread</li>
       <li>Learn  Guitar </li>
       <li  class="important">Pay  Bills</li>
       <li  class="postponed">Wash  Car</li>
   </ul>
</div>

I wrote the specificity of the selectors at the side. I though the colors of the list (per line) should be
cyan
cyan
green
cyan

but it comes out as
blue
red
green
cyan

I don't understand how R2, with the smaller specificity, can override R3, with the bigger! Could someone explain it, please?

user5646514
  • 69
  • 2
  • 9
  • The code doesn't perform how you say it does. It's coming out blue, red, green, cyan, as the Snippet demonstrates. Also what is the significance of the R# comments? – TylerH Jan 25 '17 at 19:05
  • Also, this is probably a duplicate, but I can't find one right now. Basically: class selectors are always more specific than tag selectors, and ID selectors are always more specific than class selectors. Read [this article on specificity](https://www.smashingmagazine.com/2007/07/css-specificity-things-you-should-know/), it might help you. – TylerH Jan 25 '17 at 19:09
  • Oh, I wrote it wrong. I'll edit it. The R# comments are for mentioning the lines later in the text, but I suppose I only need 2 Rs for that. I'll change it too, thanks! – user5646514 Jan 25 '17 at 19:14
  • One way to test this easily is to put the code in JSFiddle and then add in one line of CSS (one selector) at a time, hit Run, and see what changes. – TylerH Jan 25 '17 at 19:15
  • @TylerH thanks for the links and the help with editing :) The thing is I wanted to understand why the specificity was being overwritten, I already knew the output. I searched, but apparently I missed that detail about multiple targeting. It's all sorted out now ^^ – user5646514 Jan 25 '17 at 19:20
  • 1
    Possible duplicate of [CSS: Understanding the selector's priority / specificity](http://stackoverflow.com/questions/4072365/css-understanding-the-selectors-priority-specificity) – Zach Saucier Jan 25 '17 at 20:15

2 Answers2

1

Specificity is about resolution for different rules for the same element. But here one sets for ul (R3) and the other (R2) for li, so the li takes precedence in color over its parent's rule which you think coincides.

From MDN:

Specificity only applies when the same element is targeted by multiple declarations.

Omri Aharon
  • 16,959
  • 5
  • 40
  • 58
1
  1. First of all... the outcome is blue, red, green, cyan, not red, red, ...
  2. Avoid using complex selectors. Notice that if you simplify them to:
li:first-child {color:  blue}                /* R1 - 3*/
li {color:  red}                             /* R2 - 5*/
#todo {color:  cyan}                         /* R3 - 1*/
.important {color:  green}                   /* R4 - 1*/
.postponed {color:  inherit}                 /* R5 - 2*/
li + li + li {color:  magenta}               /* R6 - 4*/

The outcome will be exactly the same.

  1. To your question, there's a proximity issue, a style for <ul> will always lose to a style for <li> (when styling <li> elements).
warkentien2
  • 969
  • 13
  • 20
  • "Don't use complex selectors at all." Depends on what you mean by "complex selectors". li + li + li is a complex selector because it contains combinators. But *every* selector here is also a complex selector, even if it only contains one compound selector. – BoltClock Jan 26 '17 at 01:09
  • @BoltClock I toned it down a bit. The example went to show that most overly complex selectors are fruit of poor programming. – warkentien2 Jan 26 '17 at 03:05