@scope Rule
Overview
In standard CSS, everything is completely global. If you write img { border-radius: 50%; }, every single image on the entire website becomes a circle. For decades, we fixed this by using complex naming conventions (BEM: .card__img) or heavy JavaScript libraries (CSS-in-JS/Styled Components). The modern @scope rule introduces true, native scoping to CSS. You can explicitly trap a block of CSS inside a specific component, ensuring it physically cannot leak out and affect the rest of the page.
Syntax
/* 1. Define the Scope Root */
/* We are trapping all these styles strictly inside the .profile-card */
@scope (.profile-card) {
/* This will ONLY style <img> tags inside the .profile-card! */
img {
border-radius: 50%;
border: 3px solid gold;
}
/* This will ONLY style .title classes inside the .profile-card! */
.title {
font-size: 2rem;
}
}
/* 2. The Scope Limit (The 'Donut' Scope) */
/* Scope starts at .modal, but explicitly STOPS when it hits a .footer! */
@scope (.modal) to (.footer) {
p { color: blue; } /* Styles text in the modal, but NOT in the footer */
}Common Pitfalls
- Using
@scopeto avoid writing good class names. While scoping prevents leaks, relying on ultra-generic tags (like stylingdiv { ... }inside a scope) still makes the CSS incredibly hard to read and debug. You should still use sensible class names. - Browser compatibility. As a cutting-edge standard, old versions of Safari or Chrome will completely ignore the
@scopeblock, meaning none of the styles will apply. Use this only in modern stacks or with PostCSS polyfills.
Interview Questions
A Donut Scope (@scope (.parent) to (.child)) creates a ring of styling. It targets elements inside the parent, but explicitly halts the styling before it bleeds down into a specific nested child component, effectively punching a 'hole' in the scope.
Real-World Example
Safely styling a Markdown/CMS block without accidentally ruining the rest of the website.
/*
CMS generated HTML is notoriously messy.
We can safely style all standard tags strictly inside the article wrapper.
*/
@scope (.cms-content) {
h1, h2, h3 { color: #333; margin-top: 1em; }
ul { list-style-type: square; padding-left: 20px; }
a { text-decoration: underline; color: blue; }
}Check Your Knowledge
Test your understanding of @scope Rule with these quick questions.