Anatomy of a Svelte Component
How a .svelte file's script, markup, and style sections fit together into one component.
阅读需 2 分钟
A .svelte file is a single component, and it has room for up to three sections: a <script> block for logic, plain markup for the template, and a <style> block for CSS. None of them are required, but most real components use all three.
<script>
let name = $state('world');
</script>
<h1>Hello, {name}!</h1>
<button onclick={() => (name = 'Svelte')}>
Change name
</button>
<style>
h1 {
color: rebeccapurple;
}
</style>The script block
Code inside <script> runs once when the component is created. It's regular JavaScript — imports, variables, functions — plus Svelte's runes ($state, $derived, $effect, $props, covered in upcoming lessons) for anything that needs to be reactive.
The markup
Everything outside <script> and <style> is your template. It looks like HTML, but curly braces { } drop into JavaScript expressions:
<p>{name.toUpperCase()} has {name.length} letters</p>You can put any expression inside { } — a variable, a function call, a ternary — but not statements like if or for. For conditional and repeated markup, Svelte has its own block syntax ({#if}, {#each}), which you'll meet in a later lesson.
Scoped styles
CSS in <style> is scoped to the component by default — Svelte adds a unique, compiler-generated class to every element the component renders and to every selector in that block, so h1 { color: rebeccapurple; } only ever affects <h1> elements rendered by this component, never <h1>s belonging to some other component elsewhere in the app.
<style>
/* Only matches <p> tags rendered by this component */
p {
line-height: 1.6;
}
</style>This is a real difference from plain CSS or CSS-in-JS libraries: there's no naming convention (like BEM) to maintain, and no runtime cost — the scoping happens once, at compile time, by rewriting your selectors and markup.
Composing components
A component becomes reusable markup by importing and using it like a tag:
<script>
import Greeting from './Greeting.svelte';
</script>
<Greeting name="Ana" />
<Greeting name="Bilal" />Each <Greeting ... /> creates an independent instance with its own state — changing one doesn't affect the other. Under the hood, this is the compiler generating separate, isolated pieces of DOM-updating code per instance, exactly as described in the previous lesson.
The rest of this course spends most of its time inside the <script> block — that's where runes, props, and events live — but keep in mind that a component is always this same three-part shape underneath.