-
-
Notifications
You must be signed in to change notification settings - Fork 68
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
[postcss-nesting] issues with :is pseudo selector #195
Comments
Hi @lubomirblazekcz! Thank you for bringing this up! Wrapping the parent selector with The nesting spec can be a bit counter intuitive because it is not a simple find/replace where the parent selector is inserted for each In general it is best to avoid nesting too deeply or using complex selectors (those using combinators like The correct source CSS would be : .ui-input {
& :is(input, textarea, .input) {
@nest :is([data-icon*="left"]) & {
padding-left: 1rem;
}
} Which becomes : :is([data-icon*="left"]) :is(.ui-input :is(input,textarea,.input)) The space before These changes were introduced in |
@romainmenke thanks for clearing this up, I've been used to use I am actually surprised that |
Hmm after further analyzing, I would expect the output be following :is([data-icon*="left"]) .ui-input :is(input, textarea, .input) This is how I would expect it to work according the spec. Which wouldn't be obviously good, because there would be no way to match top-parent selector after further nesting. I might be wrong, but this is something that is not very clear in spec. Or maybe I've missed that |
Will try to write down how the spec is defined (afaik, and I might be wrong) and how the plugin works. The relevant spec section is here : https://www.w3.org/TR/css-nesting-1/#nest-selector for simplicity I am omitting the .ui-input {
& input {
@nest :is([data-icon*="left"]) & {
padding-left: 1rem;
}
}
}
& input
:is(.ui-input) input
so actual output is At this point the selector looks like this : .ui-input input {
@nest :is([data-icon*="left"]) & {
padding-left: 1rem;
}
}
:is([data-icon*="left"]) &
:is([data-icon*="left"]) :is(.ui-input input) This matches an element with tag name The same logic without the space : .ui-input {
& input {
@nest :is([data-icon*="left"])& {
padding-left: 1rem;
}
}
}
& input
:is(.ui-input) input
so actual output is At this point the selector looks like this : .ui-input input {
@nest :is([data-icon*="left"])& {
padding-left: 1rem;
}
}
:is([data-icon*="left"])&
:is([data-icon*="left"]):is(.ui-input input) Which can be rewritten as :
This last step (3) can't be easily abstracted into plugin logic but a complex selector in This matches an element with tag name Can you pinpoint which step in this logic is unexpected? :) If at any point I say something that doesn't match the actual plugin output for a given source, please call this out. This is complicated stuff and I might be wrong about things |
The 5. is unexpected to me, why should be the parent wrapped with a, b {
& c { color: blue; }
}
:is(a, b) c { color: blue; } Anyway, what was my main concern was that it was possible to select the grandparent selector prior the I was not aware that it was not part of the spec, so this might be something I should open an issue at w3c/csswg-drafts, because selecting grandparent selector might be quite important in some cases. |
Currently with postcss gradparent can be selected folowing way, but as I said - I am not sure if that is how it was intended in the spec and it's also not ideal to repeat the grandparent selector in the @nest .a {
color: blue;
& .b {
@nest .a:not(.c) & {
color: red
}
}
}
.a:not(.c) :is(.a .b) {
color: red;
} |
As far as I know grandparent selection was never part of the spec and if the plugin worked like this before it was likely a bug :/ I would also advice against this style but that is my own opinion :) I think the intention behind the spec was to enable logical grouping of styles in a block like syntax. .element {
color: red;
width: 50px;
&:hover {
color: blue;
}
@media (min-width: 520px) {
& {
width: 100px;
}
}
} In reality much more complex things are done with it and sass like nesting is in no way spec compliant but it did set the expectations of the feature. This plugin attempts to follow the spec but this is only possible by wrapping each parent with As |
If older browsers you mean Safari, then yes 😅 To be honest I am also againts deep and complex nesting, but there are many cases when you get nested into second level and using grandparent selector in the second level is much cleaner syntax then using it at first level. And I never thought it was a bug, because less works exactly the same way :D |
Chrome also less than a year ;) In the Using this config then might be interesting : postcssPresetEnv({
features: {
'is-pseudo-class': {
onComplexSelector: 'warning',
},
'nesting-rules': {
noIsPseudoSelector: false,
}
}
}) This combo will ensure that your source code will never have unexpected results in older browsers. (if you resolve the warnings) |
Chromium browsers have the advantage of better update cycle, thanks for the info though |
@lubomirblazekcz Closing this as the plugin works as intended in this case. If the spec does change or if you encounter further issues please let us know, we will happily look into these! |
Cool, looking forward to the v7.3 release, Im having the same issue too, and using |
@shye0000 Can you clarify your comment? :)
Important notes : https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-is-pseudo-class#%EF%B8%8F-known-shortcomings |
@romainmenke ah my bad, didn't notice all that, Ill try that, thx again |
Bug description
The
:is
selector is working quite strangly for me, since the update I would rather usenoIsPseudoSelector: true
, which I think should have been default, it is quite a breaking change and there are lot of unexpected results. See below, this is when usingnoIsPseudoSelector: false
Source CSS
or
Expected CSS
or
Actual CSS
or
Does it happen with
npx @csstools/csstools-cli <plugin-name> minimal-example.css
?No response
Extra config
No response
What plugin are you experiencing this issue on?
PostCSS Nesting
Plugin version
10.1.2
What OS are you experiencing this on?
macOS, Windows
Node Version
16.13.1
Validations
Would you like to open a PR for this bug?
The text was updated successfully, but these errors were encountered: