Skip to content

Scope css styles to a different Svelte component #8635

Open
@robertadamsonsmith

Description

@robertadamsonsmith

Describe the problem

The existing ways of scoping css styles to a child component don't feel right. Either they require customisable components to expose a lot of properties for styling purposes, which does not feel right, or for :global() to be used in a way that can cause styles that are designed to target a child component to leak into other descendant components.

Describe the proposed solution

Just as :global() is used to strip the prefix from selectors, we could allow the name of a component such as :MyButton() to be used to add the appropriate prefix to a selector, so that it can target elements in a descendant component. It would look like this:

<script>
	import MyButton from "./MyButton.svelte"
</script>

<div>
	<MyButton>Click Me!</MyButton>
</div>

<style>
	div :MyButton(button){
		background-color:red;
	}
</style>

I think that a containing element would usually be necessary, to avoid the style from being applied 'globally' to all instances of MyButton (much like how :global() is generally used).

Alternatives considered

The usual approach is to use :global(), but that can cause a descendant component to be accidentally targeted as well, such as illustrated here, since the selector in the :global() section cannot be restricted to just the component that we really want to style:

<script>
	import MySheet from "./MySheet.svelte"
	import MySection from "./MySection.svelte"
</script>

<div>
	<MySheet>
		<MySection>First Section</MySection>
		<MySection>Second Section</MySection>
	</MySheet>
</div>

<style>
	div :global(div){
		background-color:red;
	}
</style>

A child selector can stop the style leaking beyond the child (i.e. div > :global(div)), but then it makes the relationship more fragile. Another way to stop the style leaking is to add uncommon class names to elements so that they can be more precisely targeted from ancestors (i.e. div > :global(.mysheet-div)), but that feels very verbose.

Another approach is to expose styles through attributes, but that requires a lot of repetitive work, and prevents styling from being expressed through css, and so doesn't feel like the correct approach.

Importance

would make my life easier

Metadata

Metadata

Assignees

No one assigned

    Labels

    cssStuff related to Svelte's built-in CSS handling

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions