Cours Svelte et SvelteKit · Module 2: Composants
Les styles en Svelte
Dans cette leçon5
Les styles en Svelte sont scoped par défaut : ils ne fonctionnent qu'à l'intérieur du composant où ils sont définis. C'est comme un sort runique de protection !
Styles Scoped
<h1>Titre dans un composant</h1>
<style>
/* Ce style s'applique UNIQUEMENT à ce composant */
h1 {
color: gold;
font-size: 2rem;
}
</style>Svelte ajoute des attributs uniques aux éléments :
<!-- Résultat dans le navigateur -->
<h1 class="svelte-abc123">Titre dans un composant</h1>Styles globaux
Parfois, tu as besoin de styles globaux. Utilise :global() :
<style>
/* Uniquement dans ce composant */
h1 {
color: gold;
}
/* Globalement - partout dans l'application */
:global(body) {
margin: 0;
font-family: 'Norse', serif;
}
/* Global à l'intérieur d'un sélecteur */
.container :global(h1) {
color: silver;
}
</style>Classes dynamiques
La directive class:
<script>
let isActive = $state(true);
let isWarrior = $state(true);
let status = $state('ready');
</script>
<!-- Ajouter une classe sous condition -->
<div class:active={isActive}>
Guerrier actif
</div>
<!-- Raccourci quand le nom de la classe = le nom de la variable -->
<div class:isWarrior>
Guerrier
</div>
<!-- Plusieurs classes -->
<div
class:active={isActive}
class:warrior={isWarrior}
class:status-ready={status === 'ready'}
>
Viking
</div>Un objet dans l'attribut class (Svelte 5.16+)
Depuis Svelte 5.16, l'attribut class accepte aussi un objet : la clé est le nom de la classe, et la valeur indique s'il faut l'ajouter. La documentation de Svelte recommande cette forme dans le nouveau code, tandis que la directive class: fonctionne toujours et que tu la croiseras dans beaucoup de projets :
<script>
let isActive = $state(true);
let isWarrior = $state(false);
</script>
<!-- Pareil que class:active={isActive} class:warrior={isWarrior} -->
<div class={{ active: isActive, warrior: isWarrior }}>
Viking
</div>
<!-- Un tableau combine classes fixes et conditionnelles -->
<div class={['card', isActive && 'active']}>
Carte de guerrier
</div>Attribut class dynamique
<script>
let type = $state('warrior');
let isActive = $state(false);
</script>
<div class="viking {type}">
Type : {type}
</div>
<!-- Expression ternaire -->
<div class={isActive ? 'active' : 'inactive'}>
Statut
</div>Variables CSS (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>Styles inline conditionnels
<script>
let health = $state(75);
</script>
<div
class="health-bar"
style="width: {health}%; background: {health > 50 ? 'green' : 'red'}"
>
{health}%
</div>Code de cette leçon : 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>Entrées de la documentation utilisées dans cette leçon
Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Que signifie le fait que les styles dans Svelte sont « scoped » (isolés) ?
2. Comment définir un style global dans un composant Svelte ?
3. Comment utiliser la syntaxe raccourcie class: quand le nom de la classe est identique au nom de la variable ?
Tâches pratiques dans le jeu
- Éditeur de code
Complète le code pour que la classe « active » soit ajoutée quand isActive vaut true