Styling in Astro
A <style> block inside an .astro component is scoped to that component automatically — no explicit keyword needed, matching Svelte's own zero-config default rather than Vue's opt-in scoped attribute.
Scoped by Default
Astro adds a unique attribute to this component's own elements at build time, so a different component's own .card rule never collides with this one — the identical technique, and the identical zero-runtime-cost result, Svelte's own scoped styles already used.
Opting Out: is:global
is:global on a specific <style> block disables scoping for just that block, letting its rules apply site-wide from wherever the component happens to be used.
A Real Site-Wide Stylesheet
For genuinely site-wide styling — this project's own established dark theme, for instance — a plain imported .css file in a shared layout's frontmatter is the natural choice, applying unscoped to the whole page.
define:vars: Frontmatter Values Inside CSS
define:vars binds a frontmatter value directly into a real CSS custom property, usable anywhere inside that component's own scoped <style> block — no inline style attribute and no separate CSS-in-JS library required to bridge computed values into CSS.
Sass Support, Out of the Box
Installing the sass package is the only setup required — no bundler configuration to write. lang="scss" on any <style> block enables real Sass syntax, still scoped by default the same as plain CSS.
Scoped Styles, Compared
| Framework | Scoped by Default? |
|---|---|
| React | No — needs CSS Modules or a separate styling library |
| Vue | Opt-in via <style scoped> |
| Svelte | Yes — automatic, zero configuration |
| Astro | Yes — automatic, zero configuration, same mechanism as Svelte |
Coding Challenges
Build two components that each style an h3 tag differently in their own scoped <style> block, and confirm both render with their own distinct styling when placed on the same page.
📄 View solutionUse define:vars to bind a frontmatter color variable into a CSS custom property, applied inside that component's own scoped style block.
📄 View solutionAdd a global.css stylesheet imported from a shared layout applying a site-wide dark background, and confirm a component's own scoped styles still layer correctly on top of it.
📄 View solutionChapter 6 Quick Reference
- Scoped by default —
<style>is automatically scoped, same mechanism as Svelte, unlike Vue's opt-inscoped is:global— opts a specific style block out of scoping- Imported global stylesheet — the right tool for genuinely site-wide styling
define:vars— binds a frontmatter value into a real CSS custom property, no CSS-in-JS library needed- Sass —
npm install sasspluslang="scss", no bundler config required - Next chapter: Islands Architecture In Depth