Skip to main content
🎨 CSS as a design system·Module B8 · Lesson 6
TaskBuild a card with @scope. @scope (.card) { h2 { color: #3B82F6; margin: 0; } p { color: #71717A; } .cta { background: #3B82F6; color: white; padding: 8px 16px; border: none; border-radius: 6px; } }. Card has h2, p, button.cta.

@scope — declarative local styling

100 XP7 min
Theory

CSS gets scoping in 2024

@scope (.card) {
  h2 { color: #3B82F6; font-size: 1.25rem; }
  p { color: #71717A; }
  .cta { background: #3B82F6; }
}

Every rule inside @scope (.card) only matches inside a .card. The h2 selector becomes equivalent to .card h2 — but with the bonus of NOT crossing into nested .cards.

scope-end: stop the cascade boundary

@scope (.card) to (.nested-component) {
  /* Styles apply to .card but STOP at .nested-component */
  h2 { color: blue; }
}

The to clause stops the scope at the second selector. Useful when you embed a component that should NOT inherit the parent's styles.

When this beats CSS modules / nested rules

/* Old way — repeat .card in every selector */
.card h2 { ... }
.card p { ... }
.card .cta { ... }

/* @scope way — declare once */
@scope (.card) {
  h2 { ... }
  p { ... }
  .cta { ... }
}

Cleaner. Lower specificity (scope adds 0 to specificity). And explicit boundaries.

Browser support

Chrome / Safari shipped 2023-24. Firefox shipped 2025. Treat as widely supported in late 2026; until then, a CSS modules / nested fallback works fine.

🔒

Sign up to start coding

Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.

Sign up — free trial →

First 10 lessons in each track are free. No card needed for those.

PreviousNext lesson →

Get one Python or web tip a day — by email

Short, hand-written, no spam. Unsubscribe in one click.