SkillByAIOpen interactive version →

Lesson 3 / 25

Anatomy of a Component

Script, markup and scoped style in one file.

Three parts of a .svelte file

A component has an optional <script> (add lang="ts" for TypeScript) that runs once per component instance, markup that mixes HTML with {expressions}, and an optional <style> block. Styles are scoped: the compiler adds a hash class such as svelte-1abc23 so a p { } rule only affects this component's paragraphs; use :global(...) to opt out. A <script module> block (Svelte 4: <script context="module">) runs once when the module is first evaluated and can export helpers. Components are imported like modules and used with capitalised tags. Attributes use {} and have shorthand {src} for src={src}.

Script, markup, style

Card.svelte using another component.

<script lang="ts">
  import Avatar from './Avatar.svelte';

  let name = 'Asha';
  let src = '/avatars/asha.png';
</script>

<article class="card">
  <Avatar {src} alt={name} />
  <p>Hello, {name.toUpperCase()}!</p>
</article>

<style>
  /* scoped: only affects <p> inside this component */
  p { font-weight: 600; }
  .card { padding: 1rem; border-radius: 0.5rem; }
  /* opt out of scoping for nested markdown, for example */
  .card :global(a) { color: inherit; }
</style>

Unused selectors are flagged

The compiler warns about CSS selectors that match nothing in the markup, which helps keep component styles tidy.

Quick check: What does Svelte do to a p { } rule in a component style block?

  • Moves it into an inline style attribute
  • Applies it to every paragraph in the app
  • Ignores it unless marked :global
  • Scopes it to that component with a generated class
Answer

Scopes it to that component with a generated class — Component styles are scoped by default.