Open stalkerg opened 2 years ago
Node adapter:
dev
As you can see, on Node adapter, such CSS before the title wich in the head.
This will need a minimal reproduction if we're to create a test case and possible fix
Okey, I will try to do it ASAP.
@Rich-Harris okey, reproducing is very trivial:
npm create svelte@latest my-app
npm run dev
, and as you can see, all CSS after <title>
:
npm run preview
, and as you can see, all CSS before <title>
:
do you need something even simpler? I can try to do it or try to make a test case, but it seems like you can reproduce it in any trivial scenario.
This shows tags coming before/after the <title>
, but to build a test case around this the styles themselves need to differ between prod and dev
We just need to add any <link
to css in <svelte:head>
and this will be illustrated, depending on before/after some rules will be overridden each over or not.
I am currently moving into a new house and can probably make a unit/integration test only next week.
On preview above: right window is preview
mode, left is dev
@Rich-Harris i made an simple reproduction https://stackblitz.com/edit/sveltejs-kit-template-default-g3jmhk?file=src/routes/+page.svelte
Main points:
+layout
has imported styles for <h1>
+page
has its own styles for <h1>
dev mode
, imported styles in +layout
have priority over page styles+page
styles override the styles imported into +layout
. In my opinion, the component CSS styles should have a chance to overwrite any styles from <svelte:head>
and +layout
.
The issue here is that when you import './styles.css'
, Vite injects the contents in a <style>
element at the end of the <head>
. So the SSR'd page looks like this...
<style><!-- imported styles injected by SvelteKit --></style>
<!-- <svelte:head> content, potentially including styles -->
...but after hydration, it looks like this:
<!-- <svelte:head> content, potentially including styles -->
<style><!-- imported styles injected by Vite --></style>
In prod, it looks like this:
<link rel="stylesheet" href="[bundled styles]">
<!-- <svelte:head> content, potentially including styles -->
The only way SvelteKit could make this consistent is by matching Vite's dev-time behaviour — placing imported .css
files at the end of the <head>
. But that seems rather undesirable. Perhaps if there was a way to tell Vite where to inject styles, these problems could be avoided. Beyond that, I'm not sure we have any great options.
hmm it's a huge stopper, in that case not possible to use any external CSS with SvelteKit especially if you must overwrite something.
Does this issue only happen if you're doing stuff in <svelte:head>
? Because if so my best advice would be 'don't do that'
Yes, but how to support dynamic external CSS? The URL depends on the current user's theme choice.
<link href="{env.style_cdn_host}/{env.site_theme}.css?v=144" rel="stylesheet" type="text/css" />
I think I can implement by %mycssurl%
replacement in app.html
but in that case, a user must reload the full page, as I understand.
Yes, but how to support dynamic external CSS? The URL depends on the current user's theme choice.
<link href="{env.style_cdn_host}/{env.site_theme}.css?v=144" rel="stylesheet" type="text/css" />
I think I can implement by
%mycssurl%
replacement inapp.html
but in that case, a user must reload the full page, as I understand.
This doesn't solve the problem in this topic, but for switching CSS themes loaded dynamically from external sources, you can do all the work in <head>
rather than in the <style>
of the component.
I mean, those styles that can be overwritten in the dynamically loaded theme should also be loaded via head > link
.
https://stackblitz.com/edit/sveltejs-kit-template-default-ikbt4z
Yes, but how to support dynamic external CSS?
You could do it imperatively — add this to src/app.html
...
<link id="theme" rel="stylesheet" href="REPLACE_ME_IN_HANDLE_HOOK">
...then do this sort of thing:
$: document.querySelector('theme').href = `${style_cdn_host}/${site_theme}.css?v=144`;
That way, you have complete control over where in the <head>
the stylesheet goes, and with it the order in which stylesheets are applied
@Rich-Harris seems like working BUT looks awkward especially because I should share session data between +layout.server.js
and hooks.server.js
by a global variable (also it's probably can be the point of race condition).
Describe the bug
I have global styles in the
<svelte:head>
for the main +layout.svelte. On the dev env, the components<styles>
put after main<svelte:head>
but adapter-node inject it before<svelte:head>
. As you can understand, style and behavior depend on order, and some of my rules are not working as I expected.Reproduction
Compare CSS position for dev and adapter-node relative
<svelte:head>
.Logs
No response
System Info
Severity
blocking all usage of SvelteKit
Additional Information
No response