Styles and the class: directive
Styles in a component's <style> block are scoped: they apply only to the markup of that file. You can safely write short selectors like li or .done — they will not affect other components.
Scoped styles
<!-- src/lib/components/TodoItem.svelte -->
<script>
let { todo } = $props();
</script>
<li>{todo.text}</li>
<style>
li {
padding: 6px 0;
border-bottom: 1px solid #eee;
}
</style>Task items get padding and a bottom line, while other li elements on the site stay as they were. Svelte adds a special class like svelte-1x2y3z to the component's elements and appends it to the selectors — this is how a style is tied to the file.
The class: directive
To add a class conditionally, use the class:name={condition} directive:
<!-- src/lib/components/TodoItem.svelte -->
<script>
let { todo } = $props();
</script>
<li class:done={todo.done}>{todo.text}</li>
<style>
.done {
text-decoration: line-through;
color: #999;
}
</style>Finished tasks are struck through and grey. When todo.done becomes false, the class is removed. If a variable has the same name as the class, there is a shorthand: class:done.
A class from an expression
The class attribute also accepts an expression. It is handy when the class is chosen from several:
<script>
let { priority } = $props();
</script>
<span class="badge {priority === 3 ? 'high' : 'normal'}">Priority {priority}</span>The element always gets the badge class and one of the classes high or normal.
Inline styles: style:
For a single CSS property there is the style: directive:
<script>
let progress = $state(40);
</script>
<div style:width="{progress}%" style:background="green">{progress}%</div>The bar takes 40% of the width. When progress changes, so does the width.
Global styles
Styles for the whole site go into a regular CSS file, for example src/app.css, imported in the root layout src/routes/+layout.svelte with the line import '../app.css'; (layouts are covered in the SvelteKit chapter). Inside a component, a single selector can be made global by wrapping it in :global(...):
<!-- src/routes/+layout.svelte -->
<style>
:global(body) {
font-family: system-ui, sans-serif;
}
</style>Common mistake
Trying to style elements inside a child component from the parent: writing li { color: red; } in +page.svelte and expecting the items from TodoItem to turn red. The parent's scoped style does not reach another component's markup. Style elements in the component where they are declared, or pass a class through a prop.