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 rules for CSS Nesting 1 specification #6421

Open
romainmenke opened this issue Oct 22, 2022 · 7 comments
Open

Add rules for CSS Nesting 1 specification #6421

romainmenke opened this issue Oct 22, 2022 · 7 comments
Labels
status: needs discussion triage needs further discussion

Comments

@romainmenke
Copy link
Member

What is the problem you're trying to solve?

css-nesting-1 is being implemented in Chrome. The specification isn't final yet and it might change in the next few weeks.

There are some issues where linters might help authors write correctly nested CSS.

.foo {
  bar & {} /* ambiguous nesting */
}
::before {
  bar & {} /* pseudo elements are not allowed */
}

At the moment we still need to wait for the final specification for all issues to surface.

What solution would you like to see?

Some stylelint rules that warn authors when they write nested selectors that are invalid or ambiguous.

Is there interest to add this to stylelint?

@jeddy3 jeddy3 changed the title Rules for nested CSS following css-nesting-1 Add rules for CSS Nesting 1 specification Oct 22, 2022
@jeddy3
Copy link
Member

jeddy3 commented Oct 22, 2022

@romainmenke Thanks for the request and for using the template.

Is there interest to add this to stylelint?

Yes, absolutely! I'm glad you created an issue. I've been meaning to open one myself since the discussion about the nesting spec in #6294 (comment).

In that issue, we touched on these three nesting patterns:

/* this use of the nesting selector at the top level is valid, but won't match anything */
&.foo {}
/* this is valid, but probably unintentional */
{
  && {}
}
/* these are equivalent */
a {
  @media (orientation: landscape) { color: red; }
}

a {
  @media (orientation: landscape) { & { color: red; } }
}

Some stylelint rules that warn authors when they write nested selectors that are invalid or ambiguous.

Rules that warn about invalid or ambiguous patterns are a perfect fit for Stylelint. We should eventually add rules to catch:

.foo {
  bar & {} /* ambiguous nesting */
}

And

::before {
  bar & {} /* pseudo elements are not allowed */
}

The patterns above could fit into one of our existing or upcoming categories:

Or we may need a new category or two, e.g. no-ambiguous.

The specification isn't final yet and it might change in the next few weeks.

I suggest any rules are first created as community plugins (perhaps bundled into a plugin pack) while the spec stabilises and is adopted by browsers. It's easier to experiment and make changes in plugins than it is to built-in rules.

The closer the plugins follow our conventions for rules and criteria for inclusion the easier it'll be to port them to built-in rules when the time is right.

I'll label this issue as a discussion so that it can be a place to chat about:

  • the names, options and capabilities of the plugins
  • what other patterns, in addition to the 5 above, that we'd like to lint
  • progress of any plugins
  • when the time is right to add built-in rules

Everyone's welcome to chime in. There are opportunities for us to help people write good and consistent nesting CSS.

@jeddy3 jeddy3 added the status: needs discussion triage needs further discussion label Oct 22, 2022
@romainmenke
Copy link
Member Author

romainmenke commented Nov 4, 2022

Another case :

div {
  .foo, textarea { … }
}

div {
  .foo &, textarea & { … }
}

This is fully valid but mutations can easily make it invalid.

  • splitting .foo and textarea into two rules -> textarea {} is invalid
  • removing .foo -> textarea {} is invalid
  • re-order .foo, textarea -> textarea, .foo {} is invalid

Some authors might prefer to enforce a style where each selector in a list is always valid even when the list changes.

div {
  .foo, & textarea { … }
}

div {
  .foo &, :is(textarea) & { … }
}

@sesse
Copy link

sesse commented Nov 5, 2022

Rather than enforcing :is(textarea), why not & textarea?

@romainmenke
Copy link
Member Author

romainmenke commented Nov 5, 2022

Rather than enforcing :is(textarea), why not & textarea?

Updated, I typed this out too quickly.
There are two separate cases, one requires &<space><type>, the other :is(<type>)

@jeddy3
Copy link
Member

jeddy3 commented Feb 25, 2023

Article from Webkit on nesting.

It have an example of #6421 (comment) in it:

ul {
  padding-left: 1em;
  :is(article) & {
    padding-left: 0;
  }
}

@osmestad
Copy link

Not a solution for everything, but the ambiguous nesting case I think it can be blocked with this:

'selector-nested-pattern': '^\\W',

(In other words, not allowing nested selectors to start with a letter)

@romainmenke
Copy link
Member Author

the restriction on idents might be dropped in the near future : w3c/csswg-drafts#7961 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs discussion triage needs further discussion
Development

No branches or pull requests

4 participants