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-shadow-no-unmatchable #5575

Open
renet opened this issue Oct 7, 2021 · 6 comments
Open

Add selector-shadow-no-unmatchable #5575

renet opened this issue Oct 7, 2021 · 6 comments
Labels
status: ready to implement is ready to be worked on by someone type: new rule an entirely new rule

Comments

@renet
Copy link

renet commented Oct 7, 2021

What is the problem you're trying to solve?

My team develops a web components library, which comes with the usage of css selectors like :host and ::slotted(). Especially the last one allows only for selectors on the 1st level (light DOM "skin"), as explained here. Thus, selecting any child of a slotted element is not possible, like for example:

::slotted(p span) { /*...*/ }

/* or */

::slotted(p) span { /* ... */ }

for a DOM like

<custom-component>
  <p>Hello <span>world</span>.</p>
</custom-component>

But it's easy, especially for devs new to web components / the shadow DOM, to make that mistake and try to use selectors like these. Right now, there seems to be no rule that prevents a developer from making these mistakes.

What solution would you like to see?

A new rule that throws an error, if a developer tries to write a selector, that by definition can never select anything. Afaik, this would at least apply to selectors like:

::slotted(div a) {}
::slotted(div) a {}
::slotted(::slotted(div)) {}
::slotted(a):hover {}
::slotted(> div) {}
::slotted(:host) {}
::slotted(div::before) {}
div :host {}
:host(> .class) {}
:host(div a) {}

/* but also probably selectors like */

div::after a {}
div::after::before {}

/* and probably many more. */

If there's rules for what I am looking for, then I'm sorry, but I didn't find any. I assume, that the selector-disallowed-list rule might be used as a workaround to achieve what I want, but this rule is actually part of the set of rules used to "limit language features" and I expect the above examples to be explicitly not part of the language features. Thanks for any replies in advance!

@jeddy3
Copy link
Member

jeddy3 commented Oct 8, 2021

@renet Thanks for using the template and sharing your suggestion in good detail.

A new rule that throws an error, if a developer tries to write a selector, that by definition can never select anything.

That sounds very useful.

If there's rules for what I am looking for, then I'm sorry, but I didn't find any.

We don't have a built-in rule for this yet.

I assume, that the selector-disallowed-list rule might be used as a workaround to achieve what I want

That's correct. The *-disallowed/allowed-list rules can be used for this type of thing, but cater to simple use cases. A dedicated rule or plugin is usually best for a complex use case like this.

but this rule is actually part of the set of rules used to "limit language features" and I expect the above examples to be explicitly not part of the language features

Yes, this new rule would fall into the possible errors category under the selector heading.

/* and probably many more. */

The scope of rule will need clarifying. We may need one catch-all rule, or smaller more focused ones, e.g. one for web components and another for ::after/before etc. I suggest creating a plugin. It'll allow us all to get a sense of the scope. We can roll into Stylelint as a built-in rule (or rules) later down the line, as it's easier to experiment within plugins than make breaking changes to built-in rules.

I'll label as discussion in case anyone else wants to chime in, but I recommend going ahead and experimenting within a plugin. The name stylelint-selector-no-unmatchable would be in line with our conventions. If you do create a plugin, feel free to link to it in this thread so that others can start using it and help to map out the scope.

@jeddy3 jeddy3 changed the title Prevent impossible selectors (especially related to shadow DOM) Add selector-no-unmatchable Oct 8, 2021
@jeddy3 jeddy3 added the status: needs discussion triage needs further discussion label Oct 8, 2021
@Mouvedia
Copy link
Contributor

Mouvedia commented Mar 16, 2022

If we were to add a rule what about encompassing all functions that require one "simple selector"?
One potential option of such a rule would be something like not-lvl-3 (boolean) which would reject :not(div, .foo) and require the more cross-browser :not(div):not(.foo).

ref https://caniuse.com/css-not-sel-list

@jeddy3 jeddy3 changed the title Add selector-no-unmatchable Add selector-shadow-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

jeddy3 commented Mar 17, 2022

With the possibilities in #5907 and @Mouvedia's suggested feature above, it feels like there's lots of scope for linting selectors that are unmatchable in some way.

Let's break these into small and more focused rules.

Let's limit this issue to disallowing unmatchable shadow dom selectors.

  • Name: selector-shadow-no-unmatchable
  • Primary option: true
  • Autofixable: No
  • Message: Unexpected unmatchable shadow selector "$selectors"
  • Description: "Disallow unmatchable shadow selectors"
  • Extended description: (need something here about how they aren't matchable)
  • Section: "Avoid errors" -> "Unmatchable"

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.

@Mouvedia Can you open a new issue for your suggestion so that we can flesh out the details?

@Mouvedia
Copy link
Contributor

Can you open a new issue for your suggestion so that we can flesh out the details?

This is too specific (niche cross-browser + only one pseudo-class) to warrant its own rule.
That's why I was advocating for a single rule that cover all cases* in which the function requires a "simple selector".

* to be tallied, 2 for now

@jeddy3
Copy link
Member

jeddy3 commented Mar 17, 2022

That's why I was advocating for a single rule that cover all cases* in which the function requires a "simple selector".

Yes, that sounds like a good scope for the rule. Let's open a new issue so that we flesh it out.

@Mouvedia
Copy link
Contributor

That's why I was advocating for a single rule that cover all cases* in which the function requires a "simple selector".

Yes, that sounds like a good scope for the rule. Let's open a new issue so that we flesh it out.

#5974

@jeddy3 jeddy3 changed the title Add selector-shadow-no-unmatchable Add selector-shadow-no-unmatchable Sep 28, 2022
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

No branches or pull requests

3 participants