css

Does repeating a classname in a CSS rule increase its priority?


Suppose I have a <div>:

<li class="menu-item"> ... </li>

Could somebody tell me if I can use li.menu-item.menu-item.menu-item { ... } to make this css rule has a higher priority?

Update:

Here is the codes to illustrate this:

<ul>
    <li class="menu-item dark">Item 1</li>
    <li class="menu-item dark">Item 2</li>
    <li class="menu-item dark menu-item-special">Item 3</li>
    <li class="menu-item dark">Item 4</li>
</ul>

.menu-item.dark {
    background: #333;
    height: 40px;
    line-height: 40px;
    margin-bottom: 10px;
}
.menu-item-special.menu-item-special.menu-item-special {
    background: blue;
}

There is also a jsfiddle: http://jsfiddle.net/wenjiehu/6hycnscy/

You can see that the background colour of "Item 3" is blue.


Solution

  • This isn't good practice because you have to go to the spec to confirm it, but interestingly enough, it will have an effect.

    Oddly enough repeating a class on a CSS declaration will boost its specificity!

    I didn't believe it, but if you consult the CSS spec, there is nothing that precludes repeating a class to increase specificity:

    • count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
    • count the number of ID attributes in the selector (= b)
    • count the number of other attributes and pseudo-classes in the selector (= c)
    • count the number of element names and pseudo-elements in the selector (= d)

    So in your example:

    .menu-item.dark {} 
    /* a=0 b=0 c=2 d=0 -> specificity = 0,0,2,0 */
    li.menu-item-special.menu-item-special.menu-item-special
    /* a=0 b=0 c=3 d=0 -> specificity = 0,0,3,1 */
    

    So that latter actually wins!


    To add more context, specificity rules are hierarchical, so below #foo beats your rule, as does !important:

    #foo
    /* a=1 b=0 c=0 d=0 -> specificity = 0,1,0,0 */
    li.menu-item-special.menu-item-special.menu-item-special
    /* a=0 b=0 c=3 d=0 -> specificity = 0,0,3,1 */
    

    Note: I've only tested this on Chrome and IE8. Because of its undefined nature some browsers may act differently.