4.9 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 selector globally, use the :global(...)
modifier.
<style>
:global(body) {
/* this will apply to <body> */
margin: 0;
}
div :global(strong) {
/* this will apply to all <strong> elements, in any
component, that are inside <div> elements belonging
to this component */
color: goldenrod;
}
p:global(.red) {
/* this will apply to all <p> elements belonging to this
component with a class of red, even if class="red" does
not initially appear in the markup, and is instead
added at runtime. This is useful when the class
of the element is dynamically applied, for instance
when updating the element's classList property directly. */
}
</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>
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" />