Is your feature request related to a problem? Please describe.
Right now Sapper treats global styles the way Svelte does: it includes these styles on every single component of the app, no matter what. I think it can be better.
What a typical webapp consists of?
We all use global styles, whether you're fond of BEM or some CSS framework. Most of them allow you to only pick the things you need, like separate components, and build the smallest possible bundle.
To match the above structure:
/app/legacy and /app/new can have very different styling, possibly even different CSS frameworks at all!Describe the solution you'd like
So I think Sapper (or Svelte Kit) has potential to make this all style separation very simple, predictable and scalable to any amount of apps at all. All we need is to restrict global styles down to a single route if they were declared in a layout component.
Svelte can never be sure if you will or will not have B.svelte in the subtree of the component A.svelte, so if you define global styles anywhere, you'll get them everywhere.
But with Sapper It's quite safe to assume, that the styles are global only in the current subtree of the paths if you define them in a layout component. So it adds a new layer of style isolation.
Describe alternatives you've considered
How important is this feature to you?
Quite important. I use Sapper as a primary tech for my app, I was thrilled by the possibility to use it universally for my whole app. Later I was shocked (though it is obvious in retrospective) to see that global styles are, you know, global. Will need to come up with some solution to it.
I also think it's a very cool feature to have.
I think the :global() modifier should solve your problem?
In some layout high up:
<style>
main :global(main) > .someClass {
color: green;
}
</style>
<main>
<slot />
</main>
@kevmodrome The correct selector would be :global(main) .red.
But yes, sure, currently there's a way to isolate global styles in Sapper, but this feature request is more about the fact that user will load a lot of stylesheets at the same time even though most of it will never ever be used.
As I said, this exact style rule (it would look something like this after bundling: main .red.svelte-r89tm3{color:red}) would be included into a single huge CSS-file and will be downloaded on every single page, and you have no real control over it. Now imagine having both legacy app style and new app style downloaded by the user, that comes to your landing page. Can be improved, isn't it? 馃槃
I just realised I got the selector backwards, it should be main :global(.someClass). It would be cumbersome but you could probably split out the different parts of css depending on what you're after using a preprocessor 馃槵.
I see the problem but does it really make sense to have one Sapper app for multiple websites?
@kevmodrome Why not?
I use Sapper as main tech in my soon to be released app (shameless plug). I reuse a lot of styling (inputs, buttons, columns, etc.) and logic components (such as tooltips, modals, form handling, etc.) between the landing page and the app.
I _can_ find a way around current problem (I listed two of the possible solutions in the request), but is any of it really better in any sense?
This relates to the styles discussion which is currently / always ongoing. I don't think we would want to implement any sapper specific style handling, and with the move to kit, this feature would need a rethink. This isn't to say that this feature isn't valuable or required, just that this would be the wrong place for it.
Closing for now, as this isn't likely to happen, and focus should be on the styling discussion taking place on Svelte.
@antony Thanks for your reply!
to the styles discussion which is currently / always ongoing
I happen to use Svelte and Sapper in particular extensively in production with a relatively big application (180 components, 200 TS files). If I can be of any service in these ongoing discussions I'll be very glad to help and share ideas. Is there any particular place where said discussions happen? Is it primarily the RFCs or mostly in Discord rooms?
I don't think we would want to implement any sapper specific style handling
Apparently, there's already some specific style handling happening. I was told this behavior is specific to Sapper. By default Svelte puts global styles in component's code, it just does not isolate the specific rules. These rules will be fetched with the component and applied to the whole DOM after first mount 鈥斅爓hich would be totally fine in my case!
But Sapper puts component's global styles in a separate huge stylesheet, making it very hard to use global styles at all. With or without SSR it will force the user to download huge amounts of unused CSS. Is it even intentional?
Global styles aren't something that Svelte promotes. They can sometimes be used as an escape hatch, but primarily it's suggested to use component styles. There not enough info here to understand your usecase and why you would require global styles - though this isn't an area I'm best equipped to help on anyway. You might try in the Svelte Discord channel to see if there's a more commonly used method of solving this problem in Svelte
There are a couple places where Svelte can offer better solutions still. E.g. Svelte needs a better accepted way of handling CSS theming. There are a handful RFCs that deal with styles / css. E.g. in Sapper, the main thing I want to do is separate out CSS handling from Sapper into a separate Rollup plugin and there's an RFC for that.
@benmccann Thanks for clarifications! Will dig into your RFCs and Discord channel.
Global styles aren't something that Svelte promotes
I understand it and find this approach reasonable to some extent. It helps me name my classes in a very obvious way (e.g. a generic .wrapper) and not be afraid it will screw up other components, so it's nice.
They can sometimes be used as an escape hatch, but primarily it's suggested to use component styles
My use case is very simple. There's a lot of CSS frameworks out there (Bulma, Bootstrap, Semantic UI, Foundation 鈥斅爐o name a few), most of which support complete customization. It would be unwise to make Sapper very hard to use with those since outside of very big corporations this is the most popular way to build apps (opinion based on NPM downloads).
It's very hard to avoid using global styles with these CSS frameworks for multiple reasons, which I can explain if needed.
There not enough info here to understand your usecase and why you would require global styles - though this isn't an area I'm best equipped to help on anyway. You might try in the Svelte Discord channel to see if there's a more commonly used method of solving this problem in Svelte
Let me try to explain it in the simplest manner possible.
I have a /old-app route, where I use Bootstrap imported as a global style in the style tag (SASS preprocess) right into the layout component.
I have a /new-app route, where I use Semantic UI imported the same way.
And I have a / with a nice landing page, where I use component styles only.
When a user comes on / he or she will download the whole bootstrap AND semantic AND component styles all at once, whether I use SSR or not. It clearly looks like a bug to me, since it is not the way it works with vanilla Svelte.
Since you're trying to build 3 apps in one, I would suggest that you really need to build 3 apps and then use routing to serve them.
This is a niche usecase where you want a site to use three different themes and two different css libraries.
In a regular spa app with global styles, your styles would conflict anyway, so I don't know why sapper needs to solve this problem.
So I would say, build different apps, or use the head tag and load global stylesheets per page in your layout. Even if we continued to maintain the current Sapper, we wouldn't add a per-route global styles modifier.
I personally use bulma myself so I'm aware that we have good support for it.
Hope this makes sense!