vite-plugin-svelte
vite-plugin-svelte copied to clipboard
Unused CSS selector "*"
Describe the bug
Using global in svelte style tag throw a warning : Unused CSS selector "*" but no rules like these are defined.
Using Svelte 5, I don't know if it could be related.
The component :
<script lang="ts">
import { Label as LabelPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: LabelPrimitive.RootProps = $props();
</script>
<LabelPrimitive.Root bind:ref class="cms-label {className}" {...restProps} />
<style lang="postcss">
:global(.cms-label) {
display: inline-block;
font-size: var(--cms-text-sm);
}
:global(.cms-label ~ :disabled) {
opacity: 0.7;
cursor: not-allowed;
}
</style>
Same error with a global attribute on the style tag instead of :global() with svelte-preprocess
Reproduction URL
https://github.com/bienoubien-studio/svelte-preprocess-unused-css-issue
Reproduction
git clone https://github.com/bienoubien-studio/svelte-preprocess-unused-css-issue.git
cd svelte-preprocess-unused-css-issue
pnpm install
pnpm dev
Then visit http://localhost:5173
Logs
[vite-plugin-svelte] src/lib/label/label.svelte:22:1 Unused CSS selector "*"
System Info
System:
OS: macOS 15.0
CPU: (8) arm64 Apple M2
Memory: 70.13 MB / 8.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.8.0 - ~/.nvm/versions/node/v22.8.0/bin/node
npm: 10.8.2 - ~/.nvm/versions/node/v22.8.0/bin/npm
pnpm: 9.1.1 - /opt/homebrew/bin/pnpm
bun: 1.1.17 - /opt/homebrew/bin/bun
Browsers:
Brave Browser: 129.1.70.117
Chrome: 124.0.6367.208
Safari: 18.0
npmPackages:
@sveltejs/adapter-auto: ^3.0.0 => 3.2.5
@sveltejs/kit: ^2.0.0 => 2.6.1
@sveltejs/vite-plugin-svelte: ^4.0.0-next.6 => 4.0.0-next.7
svelte: ^5.0.0-next.1 => 5.0.0-next.260
vite: ^5.0.3 => 5.4.8
Looks like it's may be related to svelte 5 : https://github.com/sveltejs/svelte/issues/13399
see https://github.com/sveltejs/svelte/issues/13399#issuecomment-2397764939
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
Sometimes it is needed, check this example. I defined my own spinner component that imports the svelte-loading-spinners library. I prefer to customize the CSS for each component within the component itself, but since the CSS ids and classes are defined in the svelte-loading-spinners, then I must use global.
<script>
import {Circle2} from "svelte-loading-spinners"
// Props
let {loadSpinner} = $props()
</script>
{#if loadSpinner}
<Circle2 size=60 colorOuter="#8A2BE2" colorCenter="#46B4FD"
colorInner="#FFD700" durationOuter="2s" durationCenter="1.5s" durationInner="1s" />
{/if}
<style>
:global {
.circle, .wrapper { /* These are defined in svelte-loading-spinners */
position: fixed !important;
top: 50% !important;
left: 50% !important;
margin-top: var(--margin-top) !important;
margin-left: var(--margin-left) !important;
display: flex !important;
justify-content: center !important;
align-items: center !important;
z-index: 10000 !important;
}
}
</style>
But with this code I get the warning:
[vite-plugin-svelte] src/lib/components/component/Spinner.svelte:40:1 Unused CSS selector "*"
see https://svelte.dev/docs/svelte/global-styles
svelte can be used outside of vite where you might not have other means to define global styles. But if you use vite and vite-plugin-svelte it is strongly discouraged to do this as vite offers vastly superior ways to define and load global styles.
The warning for the * selector is a bit of an unfortunate sideeffect that only happens with components that don't have targetable nodes in their own template - and only during development.
You can easily silence this warning using the new svelte5 warningFilter option in svelte.config.js
compilerOptions: {
warningFilter(w){
return w.message !== 'Unused CSS selector "*"'
}
},
or the more generic onwarn
onwarn(w, warn){
if(w.message !== 'Unused CSS selector "*"') {
warn(w)
}
}
svelte can be used outside of vite where you might not have other means to define global styles.
Ok, but i don't really think it's an argument as npx sv create myapp or the previous npm create svelte@latest myapp setup a vite project so 99% of the time people will use vite and get warnings for something they didn't do.
Ok for the compiler option, but let's say I am building a package with some components dependencies I need to style , then people using it will have multiple warnings for something they don't know about.
I feel like if I am following at 100% documentation I should not have warnings.
esp. libraries should always use scoped style or ship global styles as external css file.
users projects won't see a warning for libraries with this issue as they don't get the * selector injected.
onwarn(w, warn){ if(w.message !== 'Unused CSS selector "*"') { warn(w) } }
It seems the warningFilter stopped working with the latest svelte version: 5.10.0.
Now the Unused CSS selector "*" appears even with the warningFilter set.
did the message change maybe? filters should still work. i'd recommend checking for warning.code instead. If the issue persists please file a bug report with reproduction.
OK, I raised a Svelte bug: https://github.com/sveltejs/svelte/issues/14654
this should be done automatically again now in [email protected] and [email protected], please try again and report back if it didn't work.