Search code examples
stylelint

no-descending-specificity error reported on two different classes


I'm using stylelint with the standard format stylelint-config-standard and I'm encountering this error a lot with my stylesheets:

no-descending-specificity

An example of where it's happening is when I have CSS like:

.footer__social li a {}

.footer__social li a:hover {}

.footer__links li a {}

.footer__links li a:hover {}

and then I get the following error:

Expected selector ".footer__links li a" to come before selector ".footer__social li a:hover" no-descending-specificity.

A lot of the CSS will be like this because of using SASS like:

.footer__links {
  a {
    a:hover {}
  }
}

I don't want to have disable this if I can...

But why is it complaining? as it's two separate classes: .footer__social and .footer__links.

So these two declarations for the anchors don't have any effect on each other because they have different parent classes so what's the issue? I'd understand something like:

.footer__links a:hover {}
a {}

But I don't see the issue if it's two different classes...


Solution

  • As Stylint is advising you .footer__social li a:hover {} has a higher specificity (0-1-2 = 3) than the rule that follows it .footer__links li a {} (0-0-2 = 2). You can use this specificity calculator to confirm this.

    Source order is important in CSS, hence the warning. This rule cares about specificity, 3 is higher than 2.

    From the Stylelint docs (emphasis added):

    Here's how it works: This rule looks at the last compound selector in every full selector, and then compares it with other selectors in the stylesheet that end in the same way.

    To satisfy the noDescendingSpecificity rule your output would need to be in the order:

    .footer__social li a {}
    
    .footer__links li a {}
    
    .footer__social li a:hover {}
    
    .footer__links li a:hover {}
    

    Though personally I would also sort my rules alphabetically, as that is a) better for my OCD and b) allows for slightly better compression with gzip, e.g:

    .footer__links li a {}
    .footer__social li a {}
    .footer__links li a:hover {}
    .footer__social li a:hover {}