Nested @media transformed incorrectly for pseudo elements
I have the following css:
.this-works1.test {
background-color: hotpink;
@media screen and (min-width: 768px) {
background-color: yellow;
}
}
.this-works2 {
&.test {
background-color: hotpink;
@media screen and (min-width: 768px) {
background-color: yellow;
}
}
}
.this-does-not-work1::before {
background-color: hotpink;
@media screen and (min-width: 768px) {
background-color: yellow;
}
}
.this-does-not-work2 {
&::before {
background-color: hotpink;
@media screen and (min-width: 768px) {
background-color: yellow;
}
}
}
I am using the following code to transform it:
const { code, map, warnings } = await esbuild.transform(cssSource, {
sourcefile: `${prefix}.css`,
sourcemap: 'external',
loader: 'local-css',
target: ['chrome94', 'opera79', 'edge94', 'firefox92', 'safari15']
})
The result is the following:
.prefix_this-works1.prefix_test {
background-color: hotpink;
}
@media screen and (min-width: 768px) {
.prefix_this-works1.prefix_test {
background-color: yellow;
}
}
.prefix_this-works2.prefix_test {
background-color: hotpink;
}
@media screen and (min-width: 768px) {
.prefix_this-works2.prefix_test {
background-color: yellow;
}
}
.prefix_this-does-not-work1::before {
background-color: hotpink;
}
@media screen and (min-width: 768px) {
{
background-color: yellow;
}
}
.prefix_this-does-not-work2::before {
background-color: hotpink;
}
@media screen and (min-width: 768px) {
{
background-color: yellow;
}
}
As you can see it created these rules:
@media screen and (min-width: 768px) {
{
background-color: yellow;
}
}
Here the selector inside of @media is missing.
I was expecting something more like this:
@media screen and (min-width: 768px) {
.prefix_this-does-not-work2::before {
background-color: yellow;
}
}
I am not sure if this is an easy fix. I did not dig into the source code too much (and have no experience in Go). On top of that I am not sure if we can simply switch the target to browsers that support nesting.
In any case, if it is an easy fix all good. If it is not easy, please give me a few pointers that would allow me to do the work and submit a pull request (if we need to actually support older browsers).
Initially it seems that disabling the transformation (by using the versions listed here: https://developer.mozilla.org/en-US/docs/Web/CSS/Nesting_selector#browser_compatibility) would work for us. We however found out that these numbers are incorrect (at least for Safari). The 17.3 version does not handle nesting correctly in some cases.
@evanw Would you accept a pull request for this? If so, if you have any pointers on where to start, that would greatly help :-D
Removing the if-statement in css_nesting.go solves this error, but introduces others:
// if !sel.UsesPseudoElement() {
parentSelectors = append(parentSelectors, css_ast.ComplexSelector{Selectors: substituted})
// }
It's great to see this is covered by the tests. I'll have to trace the flow of the application to see if we can easily distinguish between the different scenario's.
This issue has been resolved, for details see https://github.com/evanw/esbuild/pull/4177