Skip to content

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

Closed
@matthew-dean

Description

@matthew-dean

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions