Skip to content

[css-nesting] A proposal, using a pseudo-class #5491

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

Closed
matthew-dean opened this issue Sep 2, 2020 · 5 comments
Closed

[css-nesting] A proposal, using a pseudo-class #5491

matthew-dean opened this issue Sep 2, 2020 · 5 comments

Comments

@matthew-dean
Copy link

matthew-dean commented Sep 2, 2020

A proposal

Related to the CSS Nesting proposal...

I was re-reading this issue, in which I talked about the conflict between the CSS Nesting proposal and Sass / Less (/ PostCSS, etc)

I think the CSS nesting proposal can be satisfied without conflicting with Sass / Less, and more closely align with CSS, by the use of pseudo-class. Specifically, replacing & with :and() (as an analog to :not())

It would be:

.component-1, .component-2 {
  :and():hover { a: b; }
} 

This would be the equivalent of:

:where(.component-1, .component-2):hover { a: b; }

That is, like :where(), :and() would add 0 specificity. (Note: this is different from the current CSS Nesting proposal, which likens the "and selector" to :is(), not :where(), but the proposal also has unique specificity rules.)

With @nest

Similarly, I think the proposal is right that the use of @nest is necessary to remove ambiguity when the "and selector" is used within a nested selector (vs the start of the nested rule), as in:

.component {
 @nest tag:and() { a: b; }
}

This would be the equivalent of:

tag:where(.component) { a: b; }

Using at root

If :and() is not nested, it would just collapse, as in, these two are equivalent, both in what they select, and in specificity:

.component { }
.component:and() { }

Uses with Less / Sass / PostCSS

This proposal would allow co-mingling with languages that currently support &, as in, with this input:

// Less code
.component {
  :and().component-2 { a: b; }
  &:hover { c: d; }
} 

The Less output would (could) be:

.component {
  :and().component-2 { a: b; }
}
.component:hover {
  c: d;
}

In other words, it's no longer ambiguous whether or not rules should flatten, and there's no conflict between the meaning of & in the existing CSS Nesting proposal and its (different) meaning in Sass / Less.

Other syntaxes

I used :and() vs :and because it seems more semantically similar to :where(), :not(), :is() etc; that is, that it's returning a selector to match, even if it doesn't have arguments. However, CSS spec authors may feel that :and is sufficient, as in:

.component {
  :and:hover {}
}

My feeling was also that arguments may be added to :and() in the future, such as partial matching of selectors, but CSS spec authors may disagree.

Another syntax possibility I considered, for brevity, would be something like an empty pseudo-class, as in :().

As in:

.component {
  :():hover {}
}

This has the drawback of no longer being a valid pseudo-class, but may be an improvement over &.

Changes to CSS parsing

Obviously, like the CSS Nesting proposal with &, a change would be needed to allow the "and identifier" at the start of a rule, but unlike the & proposal, IMO this change is not a significant, since :and() is a valid selector.


Thoughts welcome.

@jimmyfrasche
Copy link

Could :scope be used?

@matthew-dean
Copy link
Author

matthew-dean commented Sep 2, 2020

@jimmyfrasche

Could :scope be used?

It's more verbose, but technically anything could be used. The proposal is really for the use of a pseudo-selector (and some tweaks around specificity). Naming is secondary.

That said, "scope" is really the wrong concept, I think. There's not really scope within the CSS document. A nested-selector-reference really isn't related to the cascade or document tree; it's only related to the stylesheet, so scope doesn't exist.

@SebastianZ
Copy link
Contributor

Regarding :and() vs. :and, pseudo-classes only have brackets when they take parameters, independent from whether they return a selector or not, and once :and can take parameters a version with brackets can still be added. With :host/:host() there is also an example where that's the case.

Sebastian

@matthew-dean
Copy link
Author

matthew-dean commented Sep 13, 2020

@SebastianZ 👍

I suspected something like this, but I wasn't sure if this was clear in the spec. So, to be clear, I wouldn't be suggesting outside of spec conformance. Something like :and would then be what I would be recommending.

@tabatkins
Copy link
Member

Closing, since the WG explicitly accepted the current syntax (using & as the nesting selector).

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

No branches or pull requests

5 participants