svelte icon indicating copy to clipboard operation
svelte copied to clipboard

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

Open eighty4 opened this issue 1 year ago • 6 comments

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

eighty4 avatar Sep 26 '24 07:09 eighty4

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=

Prinzhorn avatar Sep 26 '24 07:09 Prinzhorn

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 avatar Sep 26 '24 15:09 eighty4

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

eighty4 avatar Sep 26 '24 15:09 eighty4

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

bienbiendev avatar Oct 01 '24 13:10 bienbiendev

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

dominikg avatar Oct 07 '24 19:10 dominikg

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>.

eighty4 avatar Oct 14 '24 20:10 eighty4