CSS Modules & Scoping
Master CSS scoping techniques — CSS Modules, Shadow DOM, CSS-in-JS, and modern CSS scoping proposals.
50 min•By Priygop Team•Last updated: Feb 2026
CSS Scoping Solutions
- CSS Modules: Locally-scoped CSS files — import styles from './Button.module.css'. Class names are automatically hashed (Button_title_a1b2c3) preventing conflicts
- Shadow DOM: Browser-native encapsulation — styles inside a shadow root don't leak out and external styles don't leak in. Used by Web Components
- CSS Cascade Layers (@layer): Control cascade order explicitly — @layer base, components, utilities. Later layers override earlier ones regardless of specificity
- @scope Rule (CSS Scoping): @scope (.card) to (.card__footer) { ... } — styles apply within a scope boundary. Native CSS scoping without JavaScript tooling
- CSS-in-JS: Styled-components, Emotion — write CSS in JavaScript. Full scoping, dynamic styles based on props. Trade-off: runtime overhead, bundle size
- Utility-First (Tailwind): Predefined utility classes (text-lg, flex, p-4) composed in HTML. No naming decisions, no dead CSS (purged in production), rapid development
Design Tokens
- What are Design Tokens: Named, platform-agnostic representations of design decisions — colors, spacing, typography, shadows, border-radius. Single source of truth
- CSS Custom Properties: --color-primary: #6366f1; — store tokens as CSS variables. Change theme by redefining variables. Cascade and inherit naturally
- Token Structure: Organize in tiers — Global tokens (--blue-500: #6366f1), Semantic tokens (--color-primary: var(--blue-500)), Component tokens (--button-bg: var(--color-primary))
- Dark Mode with Tokens: [data-theme='dark'] { --color-bg: #0f172a; --color-text: #f8fafc; } — swap tokens to change theme. All components update automatically
- Token Naming: Follow the format category-property-variant — --color-text-muted, --spacing-lg, --font-size-xl. Predictable, searchable, self-documenting
- Tools: Style Dictionary transforms design tokens into CSS, iOS, Android, and Flutter formats — designers define tokens once, every platform consumes them