no-descending-specificity error reported on two different classes
Asked Answered
J

2

10

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...

Johan answered 10/9, 2019 at 12:43 Comment(3)
Who says they have any effect on each other? They don't. What Stylelint is telling you is that you have a rule with higher specificity in your rule sheet that is above one with a lower specificity. Stylint is right, you do.Midwife
Further discussion see Fix false positives for pseudo classes in no-descending-specificityHatcher
Stylelint is right, but not helpful. The specification of the rule is too fuzzy by design.Hatcher
M
7

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 {}
Midwife answered 10/9, 2019 at 13:10 Comment(5)
But in a component based setup this isn't feasible. And if you use SASS to group stuff then this is also not feasible...Johan
I'd argue that it is is feasible. Nonetheless, it is the answer to your question. Your options are 1) disable the rule, 2) re-order your rules or 3) live with the warnings.Midwife
I'm not sure what you expect here, that the authors of Sass and Stylelint have the same goals? If you don't like the tool, don't use it. If you have a complaint about the way Stylelint works take it up with the author. I believe I have answered your question, but I cannot answer your follwo-up questions on behalf of the authors of either Sass or Stylelint; I am neither.Midwife
If my answer is correct, kindly mark it as so. If you have other questions, post them as separate questions either here or with the authors of said tools.Midwife
Good to have this clarified, thank you @SethWarburton. In my case it is picking up on a less specific selector that I have in a media query at the end of a SCSS component. One media query at the bottom is better than 5 media queries throughout the stylesheet IMO. It would be more useful if there was a rule that ensured no-descending-specificity on two selectors that ended up targeting the same thing, but as these are two completely unrelated styles, I'll be disabling this rule.Radiocommunication
D
3

You can skip this rule by adding the stylelint disable commenad to the top of the file

/* stylelint-disable no-descending-specificity */
// your styles
/* stylelint-enable no-descending-specificity */
Discretional answered 9/7, 2021 at 16:59 Comment(1)
Adding a disable comment will suppress the warning no matter if it's a false positive or if it actually makes sense.Hatcher

© 2022 - 2024 — McMap. All rights reserved.