sveltejs / svelte

web development for the rest of us
https://svelte.dev
MIT License
80.13k stars 4.26k forks source link

Unused CSS selector "*" when only using root pseudo class selector to set CSS variables #13399

Open eighty4 opened 1 month ago

eighty4 commented 1 month ago

Describe the bug

A component with a <style> block that only uses :root { } to specify CSS variables will log a warning for an unused CSS selector:

2:02:11 AM [vite-plugin-svelte] src/lib/component.svelte:89:1 Unused CSS selector "*"

It seems like every component's CSS has an implicitly added * {} at the bottom of its CSS. All components in my app include the * {}.

Only the component that uses <style> for specifying root vars flags the * {} as unused. Somehow the magic behind the scenes * {} is flagged as used for any components with CSS selectors and properties.

Reproduction

This seems to only trigger metadata.unused if the CSS only contains a root pseudo class selector and the component's markup only contains a Svelte component.

<script>
import MyComponent from './my-component.svelte'
</script>

<MyComponent/>

<style>
    :root {
        --background: #000;
    }
</style>

Logs

No response

System Info

System:
    OS: macOS 14.6.1
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 145.27 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.9.0 - /usr/local/bin/node
    npm: 10.8.3 - /usr/local/bin/npm
    pnpm: 9.11.0 - /usr/local/bin/pnpm
  Browsers:
    Chrome: 129.0.6668.70
    Safari: 17.6
  npmPackages:
    @sveltejs/vite-plugin-svelte: 4.0.0-next.7 => 4.0.0-next.7
    svelte: 5.0.0-next.259 => 5.0.0-next.259

Fourth message has guaranteed recreation steps.

Severity

annoyance

Prinzhorn commented 1 month ago

Does not happen in REPL tho

v4: https://svelte.dev/repl/cd08bbafe46342b3bea65bbd333aa867?version=4.2.19 v5: https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAA0WPTY7CMAyFr2IFFiCQKNvQjjTnoCxK6o4iUqdKHCQU9e7kBzFe2X7-nu0oJm3QC3mNgoYZhRS_yyKOgl9LLvwTDWOqvQ1O5U7rldML__TUs0EGZQMxdLD1PDDumv0lKUmbAinWlkCTcjgj8W4PMSs9V-bQwTkP89pTe_q3pfYemBNpSRmtHl38Wqxlbel6CbH4FLoSlfb8MphSSCGdtZzXwifug3r8ucSNEjZN01yqVE8oYHp2tqOeNI5Csgu43tY3Tzm1ricBAAA=

eighty4 commented 1 month ago

I corrected my OP to use a CSS variable as my local recreation has it, but that still doesn't recreate in REPL.

Here's an example I have from my local project:

{
  type: 'StyleSheet',
  start: 221,
  end: 454,
  attributes: [],
  children: [
    {
      type: 'Rule',
      prelude: [Object],
      block: [Object],
      start: 233,
      end: 441,
      metadata: [Object]
    },
    {
      type: 'Rule',
      prelude: [Object],
      block: [Object],
      start: 443,
      end: 446,
      metadata: [Object]
    }
  ],
  content: {
    start: 228,
    end: 446,
    styles: '\n' +
      '    span {\n' +
      '        border: 2px solid var(--highlight-color);\n' +
      '        display: inline-block;\n' +
      '        font-size: .8rem;\n' +
      '        font-weight: bold;\n' +
      '        padding: .25rem .5rem;\n' +
      '        border-radius: .25rem;\n' +
      '    }\n' +
      ' *{}',
    comment: null
  }
}

Every Svelte component has the * {} added to the end of its CSS. metadata.unused is only true if the CSS only contains the root pseudo class selector.

eighty4 commented 1 month ago

Does this recreate for you?

git clone https://github.com/eighty4/qwerky
cd qwerky/ui
echo "<script lang="ts">\nimport Footer from '\$lib/footer/qwerky_footer.svelte'\n</script>\n\n<Footer/>\n\n<style>\n  :root {\n    --footer-height: 4rem;\n  }\n</style>" > src/lib/qwerky_app.svelte
pnpm dev
bienoubien-studio commented 1 month ago

I got the same warning using :global() Bug reported here : https://github.com/sveltejs/vite-plugin-svelte/issues/988 Reproduction repo : https://github.com/bienoubien-studio/svelte-preprocess-unused-css-issue

dominikg commented 1 month ago

the * {} rule is injected by vite-plugin-svelte only during development to help with css hmr. (otherwise the scope class is not applied to all elements and you receive js updates if you add styles that target previously untargeted template nodes).

You should not be using svelte scoped style blocks to add global css.

https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#where-should-i-put-my-global-styles

eighty4 commented 1 month ago

Seems like a good ergonomic to have a root level/app component that can specify those global styles and variables vs jumping between the index.html <style> and the component hierarchy.

I understand why that would be the business of the hosting page and not a component, but that also seems like a personal preference. In the case of a component library that has a common component root that defaults CSS variables, the personal preference also feels like a sound use of having <style>:root{}</style>.