Skip to content

Scoped Styles

In React, you have to opt in to style scoping — CSS Modules, styled-components, Emotion, Tailwind, or some other mechanism. In Svelte, scoping is the default. Every <style> block is automatically scoped to its component at compile time. You write plain CSS class names like .card and they cannot leak into or collide with any other component.

React
// Card.jsx
import styles from './Card.module.css';
// .card in Card.module.css becomes .card_abc123 at build time
export default function Card({ title, body }) {
return (
<article className={styles.card}>
<h2 className={styles.title}>{title}</h2>
<p>{body}</p>
</article>
);
}
Svelte
<!-- Card.svelte -->
<script>
let { title, body } = $props();
</script>
<article class="card">
<h2 class="title">{title}</h2>
<p>{body}</p>
</article>
<style>
/* These class names are scoped to Card.svelte automatically */
.card { border: 1px solid #e2e2e2; border-radius: 8px; padding: 1rem; }
.title { margin: 0 0 0.5rem; font-size: 1.25rem; color: #FF3E00; }
</style>

Under the hood, Svelte compiles the <style> block by adding a unique attribute (like data-v-abc123) to every element and qualifying each selector: .card[data-v-abc123]. The compiled output is safe from collisions, just like CSS Modules — but you write zero boilerplate.

Svelte has a shorthand for toggling a class based on a condition — the class: directive:

React
function Alert({ message, isError }) {
return (
<div className={`alert ${isError ? 'alert--error' : ''}`}>
{message}
</div>
);
}
Svelte
<script>
let { message, isError } = $props();
</script>
<!-- class:error is added when isError is truthy -->
<div class="alert" class:error={isError}>
{message}
</div>
<style>
.alert { padding: 0.75rem 1rem; border-radius: 6px; background: #f0f0f0; }
.error { background: #fee2e2; color: #b91c1c; border: 1px solid #f87171; }
</style>

The class:name={condition} directive keeps your template clean — no template literals, no clsx/classnames library needed for simple cases.

In Svelte, what happens to a CSS class name like .card defined inside a <style> block?
What does "class:error={isError}" mean in a Svelte template?
A React developer is used to "import styles from './Card.module.css'". What is the Svelte equivalent?