v146 · CSS · Scope Isolation Demo

Scope Isolation Demo

Compare two scenarios: without trigger-scope, trigger names from one component bleed into another. With trigger-scope, each component's trigger names are isolated to its own subtree.

Analogy: trigger-scope works exactly like timeline-scope for scroll timelines, or @scope for CSS selectors — it creates a named boundary that prevents leakage between components.

side-by-side

Without trigger-scope — names leak ✗
Component A — timeline-trigger: --btn-trigger
Component A box
click trigger to test
Component B — animation-trigger: --btn-trigger
Component B box — also flashes! ✗
With trigger-scope — names isolated ✓
Component A — trigger-scope: --btn-trigger
Component A box (blue)
click trigger to test
Component B — trigger-scope: --btn-trigger (own scope)
Component B box (rose)

trigger-scope syntax

Value Meaning
trigger-scope: none Default. No scope established — trigger names from inside are globally visible.
trigger-scope: --foo Scopes the name --foo. Lookups for --foo starting inside this element only see triggers within this subtree.
trigger-scope: --foo --bar Multiple names can be scoped in one declaration.

code

/* Without trigger-scope: Component B accidentally uses Component A's trigger */
.component-a .trigger-btn { timeline-trigger: --activate; }
.component-b .box { animation-trigger: --activate; }  /* picks up A's trigger! */

/* With trigger-scope: each component is isolated */
.component-a {
  trigger-scope: --activate;  /* name scoped to this subtree */

  .trigger-btn { timeline-trigger: --activate; }
  .box {
    animation-name: flash-blue;
    animation-trigger: --activate;  /* finds A's local trigger */
  }
}

.component-b {
  trigger-scope: --activate;  /* separate scope, same name */

  .trigger-btn { timeline-trigger: --activate; }
  .box {
    animation-name: flash-rose;
    animation-trigger: --activate;  /* finds B's local trigger, not A's */
  }
}

see also