Description
Could you provide clarity for when :is()
is used for selectors
In the examples section, I spotted some examples that seem to suggest contradictory situations where :is()
is an equivalent to the nested code.
This example suggests that :is()
is an equivalent when there's a list of multiple selectors:
/* multiple selectors in the list are all
relative to the parent */
.foo, .bar {
color: blue;
+ .baz, &.qux { color: red; }
}
/* equivalent to
.foo, .bar { color: blue; }
:is(.foo, .bar) + .baz,
:is(.foo, .bar).qux { color: red; }
*/
And this seems consistent with this example, where it is not considered to be an equivalent to an :is()
/* & doesn’t have to be at the beginning of the selector */
.foo {
color: red;
.parent & {
color: blue;
}
}
/* equivalent to
.foo { color: red; }
.parent .foo { color: blue; }
*/
However, I then see this example where there is not a list of selectors, but it's called an "equivalent" of an :is()
.ancestor .el {
.other-ancestor & { color: red; }
}
/* equivalent to
.other-ancestor :is(.ancestor .el) { color: red; }
The difference between the first and third examples is that in the first, the parent is a single selector while in the third there is a general-descendant selector. I wouldn't consider .ancestor .el
to be a selector list because there's no comma indicating more selectors.
Request:
Could you please explicitly describe when nested CSS produces an equivalent to :is()
. i.e.:
- in cases where there are selector lists, the lists will be considered arguments of
:is()
- in cases where the selector is complex (having greater than 1 id, type, or class selector), it is considered an argument of
:is()
Could you provide clarity on the equivalency of &
and :is()
In the draft, in the section about mixing nesting rules and declarations, There is this example
article {
color: green;
& { color: blue; }
color: red;
}
/* equivalent to */
article { color: green; }
:is(article) { color: blue; }
article { color: red; }
/* NOT equivalent to */
article { color: green; }
article { color: red; }
:is(article) { color: blue; }
I understand the point about order. However, I also observe an implication regarding what &
does. This suggests that &
will produce an :is()
if it's neither preceded or seceded by another selector.
However, this contradicts an earlier example:
/* Somewhat silly, but & can be used all on its own, as well. */
.foo {
color: blue;
& { padding: 2ch; }
}
/* equivalent to
.foo { color: blue; }
.foo { padding: 2ch; }
Request
Could the incorrect example be removed? Or if they're somehow both correct, could you explain how?
Could you explicitly call out the conditions under which &&
would work.
The specifications give this example
/* Again, silly, but can even be doubled up. */
.foo {
color: blue;
&& { padding: 2ch; }
}
/* equivalent to
.foo { color: blue; }
.foo.foo { padding: 2ch; }
*/
But it has also been made very clear that the &
is not capable of sass-like concatenation.
So then what is the output of these examples?
article {
&& {
padding: 2ch;
}
}
.article {
&& {
padding: 2ch;
}
}
#article {
&& {
padding: 2ch;
}
}
The examples, as they're given, suggest one of these produces an error:
articlearticle {
padding: 2ch;
}
.article.article {
padding: 2ch;
}
#article#article {
padding: 2ch;
}
unless the &
is actually always an equivalent to :is()
. In which case each condition produces valid selectors:
article:is(article) {}
.article:is(.article) {}
#article:is(#article){}
But if this is the case, that contradicts this example where the &
seems to be "consumed".
Request
Could you expand the "Nesting Selector" section and explain when &
is an equivalent to :is()
. Could you add a section that explicitly calls out how behavior may differ with a type selector? Maybe add an example of &&
to the slightly rephrased example with type selectors