5.3 KiB
title |
---|
Styles & Classes |
- style scoping
:global
style:
class:
--css
props
Styling is a fundamental part of UI components. Svelte helps you style your components with ease, providing useful features out of the box.
Scoped by default
By default CSS inside a <style>
block will be scoped to that component.
This works by adding a class to affected elements, which is based on a hash of the component styles (e.g. svelte-123xyz
).
<style>
p {
/* this will only affect <p> elements in this component */
color: burlywood;
}
</style>
:global(...)
To apply styles to a single selector globally, use the :global(...)
modifier:
<style>
:global(body) {
/* applies to <body> */
margin: 0;
}
div :global(strong) {
/* applies to all <strong> elements, in any component,
that are inside <div> elements belonging
to this component */
color: goldenrod;
}
p:global(.big.red) {
/* applies to all <p> elements belonging to this component
with `class="big red"`, even if it is applied
programmatically (for example by a library) */
}
</style>
If you want to make @keyframes that are accessible globally, you need to prepend your keyframe names with -global-
.
The -global-
part will be removed when compiled, and the keyframe will then be referenced using just my-animation-name
elsewhere in your code.
<style>
@keyframes -global-my-animation-name {
/* code goes here */
}
</style>
:global
To apply styles to a group of selectors globally, create a :global {...}
block:
<style>
:global {
/* applies to every <div> in your application */
div { ... }
/* applies to every <p> in your application */
p { ... }
}
.a :global {
/* applies to every `.b .c .d` element, in any component,
that is inside an `.a` element in this component */
.b .c .d {...}
}
</style>
The second example above could also be written as an equivalent
.a :global .b .c .d
selector, where everything after the:global
is unscoped, though the nested form is preferred.
Nested style tags
There should only be 1 top-level <style>
tag per component.
However, it is possible to have a <style>
tag nested inside other elements or logic blocks.
In that case, the <style>
tag will be inserted as-is into the DOM; no scoping or processing will be done on the <style>
tag.
<div>
<style>
/* this style tag will be inserted as-is */
div {
/* this will apply to all `<div>` elements in the DOM */
color: red;
}
</style>
</div>
class:name
<!--- copy: false --->
class:name={value}
<!--- copy: false --->
class:name
A class:
directive provides a shorter way of toggling a class on an element.
<!-- These are equivalent -->
<div class={isActive ? 'active' : ''}>...</div>
<div class:active={isActive}>...</div>
<!-- Shorthand, for when name and value match -->
<div class:active>...</div>
<!-- Multiple class toggles can be included -->
<div class:active class:inactive={!active} class:isAdmin>...</div>
style:property
<!--- copy: false --->
style:property={value}
<!--- copy: false --->
style:property="value"
<!--- copy: false --->
style:property
The style:
directive provides a shorthand for setting multiple styles on an element.
<!-- These are equivalent -->
<div style:color="red">...</div>
<div style="color: red;">...</div>
<!-- Variables can be used -->
<div style:color={myColor}>...</div>
<!-- Shorthand, for when property and variable name match -->
<div style:color>...</div>
<!-- Multiple styles can be included -->
<div style:color style:width="12rem" style:background-color={darkMode ? 'black' : 'white'}>...</div>
<!-- Styles can be marked as important -->
<div style:color|important="red">...</div>
When style:
directives are combined with style
attributes, the directives will take precedence:
<div style="color: blue;" style:color="red">This will be red</div>
--style-props
<!--- copy: false --->
--style-props="anycssvalue"
You can also pass styles as props to components for the purposes of theming, using CSS custom properties.
Svelte's implementation is essentially syntactic sugar for adding a wrapper element. This example:
<Slider bind:value min={0} --rail-color="black" --track-color="rgb(0, 0, 255)" />
Desugars to this:
<div style="display: contents; --rail-color: black; --track-color: rgb(0, 0, 255)">
<Slider bind:value min={0} max={100} />
</div>
For SVG namespace, the example above desugars into using <g>
instead:
<g style="--rail-color: black; --track-color: rgb(0, 0, 255)">
<Slider bind:value min={0} max={100} />
</g>
Since this is an extra
<div>
(or<g>
), beware that your CSS structure might accidentally target this. Be mindful of this added wrapper element when using this feature.
Svelte's CSS Variables support allows for easily themeable components:
<style>
.potato-slider-rail {
background-color: var(--rail-color, var(--theme-color, 'purple'));
}
</style>
So you can set a high-level theme color:
/* global.css */
html {
--theme-color: black;
}
Or override it at the consumer level:
<Slider --rail-color="goldenrod" />