Closed mattpilott closed 11 months ago
note: sveltekit does not support vite5 yet. For a minimal reproduction please use npm create vite@latest --template svelte
I'm not familiar with how lightningcss works with custom media queries, but they have to be available to it when svelte components are preprocessed. app.css
is processed independently, so there would have to be a way to let lightningcss know which values exist.
You can't pass through unprocessed custom media queries yet as svelte itself doesn't understand the syntax but needs to be able to parse the style block to apply its scoped styling.
To avoid duplication in .svelte files you could look into adding a svelte css preprocessor that prepends a banner with the custom media values used in the style.
// svelte.config.js
export default {
preprocess:[{name:'custom-media-banner', style(){
// if css contains custom-media
// prepend content of custom-media.css with magic-string
// return modified css, map and dependencies:[custom-media.css]
}}]
}
some docs for preprocessors here: https://svelte.dev/docs/svelte-compiler#preprocess
see this comment too https://github.com/parcel-bundler/lightningcss/issues/402#issuecomment-1397281555
it could work in build mode when lightningcss bundler is used, but vite-dev is unbundled, so it would still be a problem then. There's not much vite-plugin-svelte can do about it, it would have to come from vite itself. But even there its a hard problem because editing app.css to update a custom-media value would have to invalidate all modules that used that value. But lightningcss itself wouldn't have the ability to track that usage and trigger the invalidations.
I suggest you try to reproduce this dev issue without svelte involved npm create vite@latest --template vanilla
create some css files where one defines custom-media, others use it and then see if vite dev is able to update accordingly. File an issue with that reproduction at vite repo.
related vite issue https://github.com/vitejs/vite/issues/11029
Yeah because of how Vite works in dev there is not much we can do here (and I'm not even sure build will works). But what you can do because Vite runs lightning css bundling for each css file, is that you can import the custom queries on every file that needs it, and then it gets inlined.
Quick example:
/* custom-medias.css */
@custom-media --from-mobile (min-width: 40em);
/* pages/page1.css */
@import "../custom-medias.css";
h1 {
@media (--from-mobile) {
color: red;
}
}
/* pages/page2.css */
@import "../custom-medias.css";
h2 {
@media (--from-mobile) {
color: blue;
}
}
Will output:
/* pages/page1.css */
@media (min-width: 40em) {
h1 {
color: red;
}
}
/* pages/page2.css */
@media (min-width: 40em) {
h2 {
color: #00f;
}
}
you can also combine the @import
with the banner preprocessor i sketched above, which means you don't have to remember to add the import manually. This allows you to use them in your svelte styles and the dependency on custom-medias.css should be tracked automatically.
as mentioned above there's nothing v-p-s itself can do about this, it's how vite works. While other bundlers (notably parcel/lightningcss itself) work differently, we can't change this, so i'll close this one as "wontfix". Please do reach out if the suggestions above don't work for you. There's also the svelte and vite discords with active helping communities if you want a more direct chat.
Describe the bug
If my app.css defines a
@custom-media
declaration and i use that in app.css everything works as expected. If i try to use that same custom media variable in a svelte component i get this error:If i add the @custom-media rule to the svelte component then it works but this of course defeats the purpose of defining custom-media rules.
Im not using a preprocessor, just vite with the lightningcss option
Reproduction URL
https://github.com/mattpilott/repro-custom-media
Reproduction
npm i
npm run dev
You can see the h1 is blue but should be red from 640px and up
Logs
System Info