Dev Encyclopedia
ArticlesToolsContactAbout

Get notified when new content drops

No spam. Just new articles, tools, and updates straight to your inbox.

Dev Encyclopedia

A reference for builders

Dev.to
Discord
WhatsApp Channel
daily.dev
Hashnode
X

Content

  • Articles
  • Tools
  • About
  • Contact

Connect

  • support@devencyclopedia.com
  • RSS Feed

Legal

  • Privacy Policy
  • Terms of Service
  • Disclaimer

© 2026 Dev Encyclopedia

Back to top ↑
  1. Home
  2. /
  3. Tools
  4. /
  5. CSS @scope Playground
Free · Live · No account

CSS @scope Playground

Edit HTML and CSS side by side and watch the @scope root and scope limit highlight live, so you can see exactly which elements are in and out before you ship it in a real component.

Zeeshan Tofiq

Zeeshan Tofiq

Full Stack Developer

How the @scope playground works

  1. 1

    Pick a preset or start typing

    Load one of the three examples — a card with a nested component, a donut scope around a quote block, or the :scope pseudo-class — or edit the HTML and CSS panes directly. Every keystroke re-renders after a short debounce.

  2. 2

    The CSS is rendered natively

    Your styles are injected into a sandboxed iframe and the browser's own @scope engine applies them. There is no CSS parser or polyfill in between, so what you see is exactly how a real browser scopes your rules.

  3. 3

    The scope boundary is read from your CSS

    The tool reads the scope root and optional limit out of your first @scope rule and injects a matching highlight layer. Because that layer is itself an @scope rule, the browser decides which elements are in scope — the highlight can never disagree with real behavior.

  4. 4

    In-scope elements get a green outline

    The scope root is drawn with a solid green outline and every in-scope descendant with a dashed green outline. When a limit is set, the excluded element is outlined in red so you can see where the scope stops.

  5. 5

    Toggle @scope off to see the leak

    Flip to Without @scope and the tool strips the @scope wrappers, letting the same selectors apply globally. Paragraphs outside the component suddenly change color — the exact problem @scope was designed to prevent.

  6. 6

    Copy the snippet

    Use Copy CSS or Copy HTML to lift the current example straight into your project. Nothing leaves your browser.

What the highlight colors mean

Turn on Highlight scope boundary and the preview draws three states. Each one answers a different question about your scope.

Scope root — solid green

Always present when your CSS has a valid @scope rule.

The single element that matches the scope root selector. Everything the scope can reach starts here. If you expected an outline and see none, your root selector matches nothing in the current HTML.

In-scope descendant — dashed green

Any element under the root that the scope still reaches.

These are the elements your scoped selectors can target. Add a scope limit and watch some of these dashed outlines disappear as those elements drop out of the zone.

Excluded (past the limit) — dashed red

Only appears when you set a scope limit with to (...).

The limit element marks the top of the donut hole. It, and everything inside it, is cut out of the scope. Your scoped rules cannot style anything from this red outline downward.

@scope syntax reference

Every form the playground understands. Paste any of these into the CSS pane.

SyntaxWhat it does
@scope (.card) { ... }Scope root only: styles .card and all of its descendants.
@scope (.card) to (.reviews) { ... }Root plus limit: styles .card down to, but excluding, .reviews and its descendants (a donut scope).
:scope { ... }Inside an @scope block, refers to the scope root element itself.
@scope (.card) { :scope > p { ... } }Relative selector: only direct-child paragraphs of the scope root.
<style>@scope { ... }</style>Prelude-less form inside a <style>: the scope root is the style element's parent.

When to reach for @scope

Common real-world scoping jobs and the root and limit that solve them. Try each one in the tool above.

ScenarioScope rootScope limit
Contain a component's styles so they don't leak out.card(none)
Protect a nested, unrelated component from parent styles.articleto (.embed)
Style a post but skip pulled-out quotes.postto (blockquote)
Theme a widget and its contents in one block.menu(none)
Style a form but exclude a third-party payment iframe wrapper.checkoutto (.stripe-mount)

Frequently Asked Questions

What does this CSS @scope playground do?

ScopeLab is a live editor for the CSS @scope rule. You edit HTML in one pane and CSS in another, and the tool renders the result in a sandboxed preview while drawing an outline around every element that is inside your scope root and, when you set a scope limit, marking the boundary where the scope stops.

It exists because @scope is easy to read about but hard to picture. Seeing the highlighted zone shrink the moment you add a scope limit builds the mental model faster than any static code snippet.

What is the difference between the scope root and the scope limit?
Scope root — @scope (.card)Scope limit — to (.reviews)
SetsThe upper boundary: where the scope beginsThe lower boundary: where the scope stops
IncludesThe matched element and its descendantsNothing — the matched element and below are cut out
Required?YesNo, it is optional
CreatesA normal scopeA donut scope with a hole in the middle
How is CSS @scope different from Shadow DOM?

Both isolate styles, but at very different costs. Shadow DOM creates a hard boundary: styles cannot cross it in either direction, inherited properties are cut off, and you usually need a custom element or a framework to set it up.

@scope is a pure CSS feature. It scopes a set of rules to a subtree without a new DOM boundary, so inheritance still flows through and outside styles still reach in unless you override them. Reach for @scope when you want to contain a component's own rules; reach for Shadow DOM when you need full encapsulation of a reusable widget.

How do I stop @scope styles from leaking into a nested component?

Add a scope limit with the to keyword. The limit selector, and everything inside it, is excluded from the scope. This is the donut pattern:

css
/* Style the card, but never touch the nested widget */
@scope (.card) to (.reviews) {
  p { color: #7c3aed; }
}

In the playground, turn on Highlight scope boundary and the .reviews element is outlined in red to show exactly where the scope ends.

Does @scope change selector specificity?

The @scope rule itself adds no specificity. A selector like p inside @scope keeps the specificity of p (0,0,1). The :scope pseudo-class, however, counts as a pseudo-class, so it adds (0,1,0) like any class would.

Proximity is the real behavior change: when two scoped rules match the same element with equal specificity, the one whose scope root is closest to the element in the DOM wins. That tie-breaker runs before source order, which surprises people. The CSS Specificity Calculator is useful for sanity-checking the numbers.

Is my HTML and CSS sent to a server?

No. Everything runs in your browser. Your markup and styles are rendered into a sandboxed iframe locally, nothing is uploaded, and there is no account or API key. You can disconnect from the network and the playground still works.

Is CSS @scope safe to use in production?

Yes. @scope reached Baseline in December 2025, meaning Chrome, Edge, Safari, and Firefox all ship it in their stable channels. For projects that still target older browsers, treat scoped styling as a progressive enhancement or keep a class-based fallback, since there is no polyfill that fully reproduces the scoping semantics.

Modern CSS playgrounds and references

Tool

CSS :has() Playground

The sibling playground for the other big modern CSS selector. Type a :has() selector against real HTML scenes and watch matches highlight live.

Tool

CSS Specificity Calculator

Paste any selector and see its (a, b, c) score. Useful for reasoning about how :scope and scoped rules interact with specificity and proximity.

Guide

8 CSS :has() Patterns You'll Actually Use

Real-world :has() patterns with copy-paste CSS, a natural companion to scoped styling for building component-aware CSS without JavaScript.

Zeeshan Tofiq

Zeeshan Tofiq

Full Stack Developer

Full stack developer with over 6 years of experience building production applications. Writes practical guides on JavaScript, TypeScript, React, Node.js, and cloud infrastructure. Focused on helping developers solve real problems with clean, maintainable code.

Enjoyed this article?

Get practical dev guides, tool updates, and new articles delivered straight to your inbox. No spam, unsubscribe anytime.