Svelte and SvelteKit course Β· Module 2: Components
Styles in Svelte
In this lesson5
Styles in Svelte are scoped by default - they only work within the component where they are defined. It is like a runic protection spell!
Scoped Styles
<h1>Title in a component</h1>
<style>
/* This style applies ONLY to this component */
h1 {
color: gold;
font-size: 2rem;
}
</style>Svelte adds unique attributes to elements:
<!-- Result in the browser -->
<h1 class="svelte-abc123">Title in a component</h1>Global Styles
Sometimes you need global styles. Use :global():
<style>
/* Only in this component */
h1 {
color: gold;
}
/* Globally - everywhere in the application */
:global(body) {
margin: 0;
font-family: 'Norse', serif;
}
/* Global inside a selector */
.container :global(h1) {
color: silver;
}
</style>Dynamic Classes
The class: Directive
<script>
let isActive = $state(true);
let isWarrior = $state(true);
let status = $state('ready');
</script>
<!-- Add a class conditionally -->
<div class:active={isActive}>
Active warrior
</div>
<!-- Shorthand when class name = variable name -->
<div class:isWarrior>
Warrior
</div>
<!-- Multiple classes -->
<div
class:active={isActive}
class:warrior={isWarrior}
class:status-ready={status === 'ready'}
>
Viking
</div>An Object in the class Attribute (Svelte 5.16+)
Since Svelte 5.16 the class attribute also accepts an object: the key is the class name, and the value says whether to add it. The Svelte docs recommend this form in new code, while the class: directive still works and you will meet it in many projects:
<script>
let isActive = $state(true);
let isWarrior = $state(false);
</script>
<!-- Same as class:active={isActive} class:warrior={isWarrior} -->
<div class={{ active: isActive, warrior: isWarrior }}>
Viking
</div>
<!-- An array combines fixed and conditional classes -->
<div class={['card', isActive && 'active']}>
Warrior card
</div>Dynamic class Attribute
<script>
let type = $state('warrior');
let isActive = $state(false);
</script>
<div class="viking {type}">
Type: {type}
</div>
<!-- Ternary expression -->
<div class={isActive ? 'active' : 'inactive'}>
Status
</div>CSS Variables (Custom Properties)
<script>
let primaryColor = $state('#d4af37');
let size = $state(24);
</script>
<div class="viking-badge" style="--color: {primaryColor}; --size: {size}px">
<span>α</span>
</div>
<style>
.viking-badge {
color: var(--color);
font-size: var(--size);
padding: calc(var(--size) / 2);
}
</style>Conditional Inline Styles
<script>
let health = $state(75);
</script>
<div
class="health-bar"
style="width: {health}%; background: {health > 50 ? 'green' : 'red'}"
>
{health}%
</div>Code for this lesson: App.svelte
<script>
// Styles in Svelte - isolated like the nine worlds
let isElite = $state(true);
let theme = $state('dark');
</script>
<div class="demo" class:elite={isElite}>
<h1>Styles in Svelte</h1>
<p>Styles are <strong>scoped</strong> by default!</p>
<div class="controls">
<label>
<input type="checkbox" bind:checked={isElite} />
Elite warrior (class:elite)
</label>
<select bind:value={theme}>
<option value="dark">Dark</option>
<option value="light">Light</option>
</select>
</div>
<div class="card {theme}">
<p>Dynamic class: {theme}</p>
</div>
</div>
<style>
.demo {
font-family: 'Georgia', serif;
max-width: 500px;
margin: 2rem auto;
padding: 2rem;
background: #1a0f0a;
color: #e8d5b7;
border-radius: 8px;
}
h1 {
color: #d4af37;
}
/* Conditional class */
.demo.elite {
border: 3px solid #ffd700;
box-shadow: 0 0 20px rgba(255, 215, 0, 0.3);
}
.controls {
margin: 1rem 0;
padding: 1rem;
background: rgba(0,0,0,0.3);
border-radius: 4px;
}
label {
display: block;
margin-bottom: 0.5rem;
}
select {
padding: 0.5rem;
background: #2c1810;
color: #e8d5b7;
border: 1px solid #d4af37;
border-radius: 4px;
}
.card {
padding: 1rem;
border-radius: 4px;
margin-top: 1rem;
}
.card.dark {
background: #0a0a0a;
color: #e8d5b7;
}
.card.light {
background: #f5f5f5;
color: #1a1a1a;
}
</style>Docs entries used in this lesson
Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. What does it mean that styles in Svelte are 'scoped' (isolated)?
2. How do you define a global style in a Svelte component?
3. How do you use the shorthand class: syntax when the class name matches the variable name?
Hands-on tasks in the game
- Code editor
Complete the code so the 'active' class is added when isActive is true