Migrating to Zazz
Adopt Zazz incrementally on existing CSS codebases using cascade layers, @scope donut scoping, and migration shims.
Zazz uses cascade layers and zero-specificity resets, allowing incremental adoption on existing codebases without full rewrites or !important overrides.
The cascade rule: unlayered rules beat layered rules
Unlayered CSS rules beat all layered CSS rules regardless of selector specificity. Existing unlayered project CSS will override Zazz layers unless wrapped in its own lower layer.
Step 1: Layer legacy CSS below Zazz
Declare layer order in your entry stylesheet and assign legacy rules to legacy:
/* entry.css */
@layer variables, reset, legacy, zazz, migrations;
@import "./legacy/app.css" layer(legacy);
@import "./zazz/index.css";Because legacy is ordered below zazz, Zazz component and utility rules take precedence where they overlap, while unstyled legacy components continue working.
The migrations layer sits above zazz.utilities. Shims in this layer override native Zazz rules
during refactoring.
Step 2: Isolate regions with @scope
Use @scope to isolate converted and unconverted DOM subtrees:
@scope (.app) to (.legacy-widget) {
/* matches inside .app, but stops at .legacy-widget */
}Use all: revert-layer inside @layer legacy to strip old styles from converted sections while retaining Zazz styles.
Step 3: Reset regions with all: revert
To reset an element tree back to browser default styles:
@scope (.takeover) to (.legacy-widget) {
:scope,
:scope * {
all: revert;
}
}Use all: revert-layer to drop to the previous cascade layer without stripping Zazz rules.
Step 4: Translate legacy classes in migrations
Bridge legacy HTML before markup updates using translation shims in @layer migrations:
/* migrations.css */
@layer migrations {
@scope (.app) to (.legacy-widget) {
.btn-primary {
--ui-button-background: var(--primary);
--ui-button-foreground: var(--primary-foreground);
}
}
}Delete each translation rule once markup is converted to native Zazz classes.
Migration workflow
- Layer: Place existing CSS in
@layer legacy. - Isolate: Apply
@scopeboundaries between converted and legacy trees. - Reset: Apply
all: revert-layeron converted sections to remove legacy styles. - Translate and convert: Add temporary shims in
migrations.css, update markup to Zazz classes, then remove shims.
Browser support
@layer, all: revert, and revert-layer are Baseline widely available. @scope is Baseline 2024 (Chrome/Edge 118, Safari 17.4, Firefox 128).