compiler icon indicating copy to clipboard operation
compiler copied to clipboard

Scoped CSS miscompilation on pseudo-elements with only pseudo-classes

Open adri326 opened this issue 2 years ago • 2 comments

What version of astro are you using?

2.4.4

Are you using an SSR adapter? If so, which one?

None

What package manager are you using?

yarn

What operating system are you using?

Arch Linux, 6.3.1

What browser are you using?

Firefox

Describe the Bug

When applying scoped CSS to pseudo-elements in CSS selectors that only contain pseudo-classes, Astro incorrectly appends the :where clause to the ::before or ::after pseudo-element, stopping it from working altogether:

<style>
/* Works as expected */
ul > li::after,
ul > .fox::after,
ul > *::after,
ul > li:not(:first-child)::after,
{
    content: "🦊";
}

/* Does NOT work as expected */
ul > ::after,
ul > :not(:first-child)::after {
    content: "🦊";
}
</style>

Expected:

The latter CSS block should compile to the following:

ul:where(.scope) > :where(.scope)::after,
ul:where(.scope) > :where(.scope):not(:first-child)::after {
    content: "🦊";
}

Actual:

Instead, it gets compiled to this:

ul:where(.scope) > ::after:where(.scope),
ul:where(.scope) > :not(:first-child)::after:where(.scope) {
    content: "🦊";
}

I'd be willing to submit a pull request for this issue, but I would need guidance as to which parts of the codebase would need to be changed.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-lyys7u?file=src/pages/index.astro

Participation

  • [X] I am willing to submit a pull request for this issue.

adri326 avatar May 11 '23 08:05 adri326

This looks like a bug in the compiler, which handles adding the scopes. I'll transfer this issue there.

If you'd like to fix this, the scoping logic mostly happen in this file! https://github.com/withastro/compiler/blob/e104c1c52728cbccc8b0e06a6dfaf7c05bcf1250/lib/esbuild/css_printer/astro_features.go

bluwy avatar May 11 '23 09:05 bluwy

Faced this today.

I have the following HTML structure:

<div class="section-join">
  <a class="join-button">Join Now</a>
</div>

I'm using PostCSS with the nesting plugin.

When I try to write pseudo element class declaration like this:

.section-join {
  & .join-button {
    &::after {
      /* */
    }
  }
}

It incorrectly compiles to

:is(.section-join .join-button)::after[data-astro-cid-j7pv25f6] { }

But when I write

.section-join {
  & .join-button::after {
    /* */
  }
}

It compiles to

.section-join[data-astro-cid-j7pv25f6] .join-button[data-astro-cid-j7pv25f6]::after { }

And styles are applied as expected.

evenfrost avatar Oct 30 '24 11:10 evenfrost