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

Add selector-anb-no-unmatchable #5907

Closed
jeddy3 opened this issue Feb 13, 2022 · 7 comments · Fixed by #6678
Closed

Add selector-anb-no-unmatchable #5907

jeddy3 opened this issue Feb 13, 2022 · 7 comments · Fixed by #6678
Labels
status: ready to implement is ready to be worked on by someone type: new rule an entirely new rule

Comments

@jeddy3
Copy link
Member

jeddy3 commented Feb 13, 2022

What is the problem you're trying to solve?

I'd like to catch nth-* selectors with zero index like:

a:nth-child(0) {}

Although it's valid CSS, it won't match anything.

From the spec:

If both A and B are 0, the pseudo-class represents no element in the list.

See: https://twitter.com/dan_abramov/status/1492277543185096704

Related to #5575 (which I suggest we break into separate rules).

What solution would you like to see?

A new rule to help me avoid errors in structural pseudo-classes:

It'll catch:

a:nth-child(0) {}
a:nth-child(+0n) {}
a:nth-child(0n+0) {}
a:nth-child(0n + 0) {}
a:nth-child(0n-0) {}
a:nth-child(-0n-0) {}
a:nth-of-type(0n) {}

It'd also disallow zero index of S selectors, e.g.:

:nth-child(0 of a) {}

This is a good candidate for using an An+B parser, e.g. the one from SWC if it's available, otherwise, we can release for just the simple case of 0 as that's the most common mistake.

  • Name: selector-anb-no-unmatchable
  • Primary option: true
  • Secondary options: None
  • Autofixable: No
  • Message: Unexpected unmatchable An+B selector "${puesdoClass}" (e.g. Unexpected unmatchable An+B selector "nth-child(0)")
  • Description: "Disallow unmatchable An+B selectors"
  • Extended description: (Something about zero indexes being a common mistake)
  • Section: "Avoid errors" -> "Unmatchable"

Any thoughts on the rule, its name and scope?


Incidentally, there's a set of rules to enforce (non-stylistic) conventions in this area too, e.g. preferring:

  • :first-child over :nth-child(1) (or vice versa)
  • :nth-child(even) over :nth-child(2n+0) (or vice versa)
  • and so on

If you'd like to add any of these to Stylelint, please open a separate issue.

@jeddy3 jeddy3 added the status: needs discussion triage needs further discussion label Feb 13, 2022
@ybiquitous
Copy link
Member

@jeddy3 The new rule sounds good to me. 👍🏼

I'm concerned about the one thing that the rule name includes a + character. We usually use a rule name for a path on file systems and an URL, so such a name may cause any problem.
For example, a + character needs to be escaped in an URL.

What do you think?

@ybiquitous
Copy link
Member

Note: In the spec URL, anb is used, instead of an+b:

https://drafts.csswg.org/css-syntax/#anb-microsyntax

@jeddy3
Copy link
Member Author

jeddy3 commented Feb 13, 2022

anb SGTM. I've updated the blueprint above.

@jeddy3 jeddy3 changed the title Add rule to catch zero An+B indexes Add selector-anb-no-unmatchable Mar 17, 2022
@jeddy3 jeddy3 added status: ready to implement is ready to be worked on by someone type: new rule an entirely new rule and removed status: needs discussion triage needs further discussion labels Mar 17, 2022
@jeddy3
Copy link
Member Author

jeddy3 commented Mar 17, 2022

I've updated the rule name to reflect #5575.

The rule should also catch negative indexes too.

I've labelled the issue as ready to implement. Please consider contributing if you have time.

There are steps on how to add a new rule in the Developer guide.

@jeddy3 jeddy3 changed the title Add selector-anb-no-unmatchable Add selector-anb-no-unmatchable Sep 28, 2022
@mattxwang
Copy link
Member

Hi all, I'm interested in taking this on - have been doing some Rust work on the side, and saw Dan's original tweet.

Were there any follow-up items from #5586 / suggested places to start? I see the Rust code for their AnPlusB parser (in swc-project/swc). However, I don't see a public export for it when doing const swc = require('@swc/core'). I'm likely missing something!

@jeddy3
Copy link
Member Author

jeddy3 commented Feb 19, 2023

Hi all, I'm interested in taking this on

That's fantastic, thank you.

We recently added CSSTree to our dependencies for the declaration-property-value-no-unknown rule. It can parse An+B syntax. We can reach for CSSTree again as this rule doesn't autofix, or we can continue to investigate adding SWC.

It'd be good to see some numbers on the package size, and whether SWC (like CSSTree) can parse just selectors.

Regardless of the parser we choose, it's should be pretty trivial to switch, if we ever want to in the future, especially with the tests in place.

(@mattxwang If we decide to go with CSSTree for this rule, please don't feel obliged to take it on as it won't have a Rust aspect which may have piqued your interest.)

@mattxwang
Copy link
Member

Thanks for the quick response @jeddy3! Didn't realize that CSSTree has this functionality, which is great!

I was able to spin up a first draft for the rule (using CSSTree) in #6678. Let me know what you think! If you'd like, I'm also happy to explore the SWC option, but it seems like CSSTree does the job quite well.

mattxwang added a commit that referenced this issue Feb 26, 2023
Closes #5907, but does not add grid-structural selectors.

---------

Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com>
Co-authored-by: Richard Hallows <jeddy3@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: ready to implement is ready to be worked on by someone type: new rule an entirely new rule
Development

Successfully merging a pull request may close this issue.

3 participants