pseudo elements must be handled like complex selectors #495
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
TL;DR;
More context
w3c/csswg-drafts#2284 (comment)
This affects every plugin that has any logic around combinators or compound vs complex selectors.
any-link
is-pseudo
I usually prefer to reduce problems to sorting because sorting is easy and algorithms aren't.
This just backfired because the AST we receive from
postcss-selector-parser
doesn't consider::before
as<combinator><tag>
.To make things worse I was not even aware that this was an issue to look out for and I was just trying to place pseudo elements at the end of selectors. (breaking
::before:hover
)Cascade layers and
any-link
were trivial to fix because they only required an exact insertion of new selector bits. I was lazy before and always just added the new bits at the end and then sorted to repair.The fixes here remove all this "bad" code and implement exact insertion.
You might see
:not(#\#)
or[href]
inserted in a different position than before this change.is-pseudo
(and thus nesting) are much more complex.We still need the sorting there, but we must consider pseudo elements as combinators.
I've written a new sorting function for
is-pseudo
and it seems to work.I avoided making too many changes in nesting as there is no browser implementation yet.
The change here is limited to not re-ordering pseudo elements in a way that changes the selected element.
For
is-pseudo
I've made the plugin a bit more strict and disallowed pseudo elements in:is()
. These are not allowed by the spec. To preserve the forgiving selector list behaviour any pseudo element is replaced by a custom pseudo element which is known to be invalid.::before
->::-csstools-invalid-before