Skip to content
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

Child combinator (>) in :has sometimes vanishes when transpiling nested css in scoped styles #11613

Closed
malte-laukoetter opened this issue Aug 14, 2024 · 3 comments

Comments

@malte-laukoetter
Copy link

malte-laukoetter commented Aug 14, 2024

Vue version

3.4.24

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-uflhun?file=vite.config.js,src%2FApp.vue&terminal=dev

Steps to reproduce

  1. run npm run dev
  2. see that the first two spans are colored and the third one is not
  3. run npm run build and npm run preview
  4. see that all three spans are colored

Please note the defined target browser version in the vite.config.js

What is expected?

Only the first two spans are colored in every case. The transpiled css works the same as the original css.

What is actually happening?

All three spans are colored as the transpiled css looses the child combinator (>) used in :deep(.foo:has(> span)).

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.20.3 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
  npmPackages:
    vue: ^3.4.37 => 3.4.37 
    pnpm: 8.15.6 - /usr/local/bin/pnpm

  System:
    OS: macOS 14.5
  Browsers:
    Chrome: 127.0.6533.100

Any additional comments?

When using scoped styles and nested css the child combinator (>) is sometimes lost when transpiling the css for browsers without support for nested css.

<style scoped>
:deep(.foo:has(> span)) {
  :deep(&) span {
    background-color: green;
  }
}
</style>

is wrongly converted into

[data-v-f41b19b6] :is([data-v-f41b19b6] .foo:has(span)) span{background-color:green}

instead of the correct

[data-v-f41b19b6] :is([data-v-f41b19b6] .foo:has(>span)) span{background-color:green}

As far as my testing has gone this only happens when :deep(&) is used in the nested part of the css.

@edison1105
Copy link
Member

It seems a bug with esbuild.
a workaround: use lightningcss instead. or cssMinify: false

export default defineConfig({
  plugins: [vue()],
  build:{
    cssMinify: 'lightningcss',
  }
});

@malte-laukoetter
Copy link
Author

Thanks for having a look and mentioning lightningcss, it does indeed seem to be a problem with esbuild

With lightningcss the expected css is generated

[data-v-f41b19b6] :is([data-v-f41b19b6] .foo:has(>span)) span{background-color:green}

Disabling the css minification is not an option as then the css does not work for browsers without nested css support.

I'll raise the bug with esbuild :)

@edison1105
Copy link
Member

Closing as not related to vue

@edison1105 edison1105 closed this as not planned Won't fix, can't repro, duplicate, stale Aug 15, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Aug 30, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants