Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix no-descending-specificity false positives for pseudo-classes #6195

Merged
merged 4 commits into from Jul 28, 2022

Conversation

ybiquitous
Copy link
Member

Which issue, if any, is this issue related to?

Closes #4010

Is there anything in the PR that needs further explanation?

This pull request aims to fix false positives for the no-descending-specificity rule about the CSS Modules :global() pseudo-class.

I'm unfamiliar with CSS Modules, so I'm unsure whether this added code specific to :global() is suitable. Perhaps, someone may know a more smart solution.

In addition, I don't know if we should address the :local() pseudo-class. Please let me know if someone knows anything about it.

See also #4010 (comment) and the reproduction demo.

*/
function checkSelector(selectorNode, ruleNode, comparisonContext) {
const selector = selectorNode.toString();
const referenceSelectorNode = lastCompoundSelectorWithoutPseudoClasses(selectorNode);
const referenceSelector = lastCompoundSelectorWithoutPseudoClasses(selectorNode);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[note] lastCompoundSelectorWithoutPseudoClasses() returns a string, not a node. So I think referenceSelector is a more readable name.

);
});

if (nodesWithoutPseudoClasses.length === 0) return undefined;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[note] If nodesWithoutPseudoClasses is empty, the old version of this function returns an empty string (''). This makes it more difficult to handle irregular values. So the current code returns undefined instead.

@ybiquitous ybiquitous marked this pull request as ready for review July 7, 2022 15:09
@richex-cn
Copy link

I created another example, But I'm unsure whether it has anything to do with this problem.

@ybiquitous
Copy link
Member Author

@richex-cn Thank you for the advice! I've added a test case via 423095a, and this fix works in that case. 👍🏼

@Mouvedia
Copy link
Contributor

In addition, I don't know if we should address the :local() pseudo-class. Please let me know if someone knows anything about it.

see https://github.com/stylelint/stylelint/blob/main/docs/user-guide/rules/about.md#user-defined-ignore

@ybiquitous
Copy link
Member Author

@Mouvedia Thanks for providing the guidance. Indeed, I think it may be better that built-in rules don't support non-standard syntaxes like CSS Modules for simplicity and maintainability.

@Mouvedia
Copy link
Contributor

I don't have an opinion. I am just saying let's be consistent.

@jeddy3
Copy link
Member

jeddy3 commented Jul 22, 2022

Just getting back around to this. It's a can of worms and I don't think I've fully grokked it yet.

I think we want to address functional pseudo-classes more generally rather than just the non-standard :global() one.

The rule currently considers the following comparable when it should not:

a :where(a, b) {}
:where(c, d) {}

See demo of false positive.

I haven't dug into the implementation of the rule deeply, but I think we should be including the :where and :is functional pseudo-classes (and their arguments) in the reference selector.

Then, as :global is a non-standard (sometimes functional) pseudo-class, we can add an ignoreSelectorsContaining: [] option, which would not compare selectors that contain any of the specified parts.

(We could add a different option which lets a user specify a list of functional pseudo-class to treat like :is and :where but I don't think its worth doing down that rabbit hole.)

@jeddy3
Copy link
Member

jeddy3 commented Jul 22, 2022

Then, as :global is a non-standard (css-modules/css-modules#264) pseudo-class, we can add an ignoreSelectorsContaining: [] option, which would not compare selectors that contain any of the specified parts.

Let's add an ignoreSelectors: [] option instead that checks against the whole selector. It's more straightforward and consistent with other rules that way. Users can then craft a regex to ignore selectors that contain :global and whatnot.

@ybiquitous
Copy link
Member Author

@jeddy3 Thanks for the suggestion. I mistakenly thought the CSS Modules specific code was required; indeed, it's unnecessary. See the commit 68bcaa which makes the test suite pass.

If the ignoreSelectors option you suggested may be needed in the future, but in this pull request, it's not needed for now.

@jeddy3 jeddy3 changed the title Fix no-descending-specificity false positives for :global() pseudo-class Fix no-descending-specificity false positives for pseudo-classes Jul 28, 2022
Copy link
Member

@jeddy3 jeddy3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

If the ignoreSelectors option you suggested may be needed in the future, but in this pull request, it's not needed for now.

👍

@ybiquitous ybiquitous merged commit dbfd6c8 into main Jul 28, 2022
@ybiquitous ybiquitous deleted the fix-no-descending-specificity-false-positives branch July 28, 2022 08:44
@ybiquitous
Copy link
Member Author

@jeddy3 Thanks for the re-review and correcting the PR title! 😄

Changelog entry added:

  • Fixed: no-descending-specificity false positives for pseudo-classes (#6195).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Fix false positives for functional pseudo-classes in no-descending-specificity
4 participants