Skip to content

Publish semantic CSS classes from design token names #6327

Description

@kof

Goals

  • Let users choose one of three CSS output modes in Publish settings:
    • Atomic CSS — safe and fast; the current default.
    • Merged classes — safe and slower; the current behavior when atomic CSS is disabled.
    • Semantic classes — unsafe and slowest; prioritizes readable exported HTML and CSS.
  • Keep Atomic CSS as the default. Existing projects must publish as they do today unless the user explicitly changes the mode.
  • In Semantic mode, expose reusable classes based on design-token names and readable classes for Local styles.
  • Keep existing Webstudio component and instance classes such as w-element; semantic user classes are added alongside them.
  • Keep each token and its own declarations mapped 1:1. Supplemental compound selectors may correct the cascade but must not change the token class itself.
  • Preserve Builder rendering wherever CSS can represent the Style Sources order. When it cannot, publish deterministically and clearly warn the user.
  • Preserve presets, breakpoints, states, custom properties, images, descendant selectors, and user-provided classes.
  • Use cascade layers so normal Local declarations reliably override presets, token classes, and token compound selectors.
  • Show all Semantic-mode risks together before publishing. Warnings must explain the impact and what the user can change, but must not block publishing or modify the project automatically.
  • Honor the same mode and diagnostics in Webstudio Cloud publishing and CLI export.
  • Optimize for readable exported output, without promising generated class names as a permanent public API across future Webstudio versions.

Implementation todos

  • Treat feat: add publish diagnostics to Builder and MCP #5930 as a blocker for the Builder warning experience. Its shared Audit dialog is required to show all affected tokens and elements with All, Errors, and Warnings views.

  • Replace the Generate atomic CSS when publishing checkbox with a three-option radio control: Atomic CSS, Merged classes, and Semantic classes.

  • Add an information tooltip to every option explaining its safety, speed, output size, readability, and portability tradeoffs.

  • Replace the boolean compiler setting with a CSS-output enum while preserving compatibility:

    • missing or atomicStyles: true → Atomic CSS;
    • atomicStyles: false → Merged classes;
    • the new Semantic value → Semantic classes.
  • Use only design tokens that are used by the published project.

  • Normalize token names with the existing kebab-case behavior: replace whitespace and unsupported separators with dashes, remove unsupported characters, and collapse repeated separators.

  • Use the normalized token name directly without a Webstudio prefix when it is a valid CSS identifier.

  • Add a token- fallback prefix only when the normalized name is empty or cannot begin a CSS identifier. Emit an audit warning that recommends renaming the token.

  • Detect token names that normalize to the same class, and collisions with existing/user classes. Keep publishing enabled, emit a warning, and tell the user which token to rename; do not rename or merge user tokens automatically.

  • Preserve Style Sources UI order in the generated HTML class attribute.

  • Emit every used token class once inside the webstudio-tokens layer. A token class contains only that token's styles.

  • Generate an automatic compound selector for every distinct used multi-token combination. Use all classes in the combination, for example .green.red, rather than adding another class to the HTML.

  • Put the final merged declarations for that Style Sources order in the complete compound selector. Generate complete selectors for supersets so a smaller combination cannot leak into a larger one.

  • Generate the equivalent compound corrections for breakpoints, states, and descendant selectors.

  • Detect when the same unordered token set is used in opposite orders and overlapping declarations would produce different results. CSS class order cannot distinguish these cases.

  • For an unrepresentable opposite-order conflict, use global token-definition order as the deterministic published fallback. Warn with the affected tokens, properties, and elements.

  • In that warning, suggest making token order consistent, moving the differing declaration to Local, or creating a new token for the combination. Do not fix the project automatically.

  • Emit generated CSS in this layer order:

    @layer presets, webstudio-tokens, webstudio-local;
  • Put token classes and compound token selectors in webstudio-tokens and Local rules in webstudio-local. Normal Local declarations must win regardless of token-selector specificity.

  • Keep unlayered custom CSS above all generated layers for normal declarations.

  • Do not add special handling for !important. If users choose it, they are responsible for its cascade behavior, including reversed layer priority.

  • Generate a Local class only when the instance has Local declarations.

  • If the instance has tokens, base its Local class on the first token, for example .green-local. If it has no tokens, base it on the instance name, for example .greeting-local.

  • Guarantee unique Local class names across the published output with deterministic numeric suffixes: .green-local, .green-local-1, .green-local-2.

  • Warn about Local-name collisions even though the numeric suffix preserves correct rendering. Recommend clearer instance names where useful.

  • Extend the shared pre-publish audit to return all Semantic-mode findings grouped by token-order conflicts, token-name collisions, invalid-name fallbacks, and Local-name collisions.

  • Show the complete grouped findings in the Builder Audit dialog and keep publishing available after warnings.

  • Use the same detector in the CLI and print the complete grouped warnings with the same suggested actions.

  • Keep Atomic and Merged compiler output unchanged apart from the settings migration.

  • Add focused tests for setting migration, used-token filtering, normalization, invalid names, collisions, stable suffixes, HTML class order, compound selectors, supersets, opposite-order conflicts, layers, Local precedence, breakpoints, states, descendants, presets, existing classes, Cloud publishing, and CLI export.

  • Update product documentation for all three modes, their safety and size tradeoffs, Semantic naming rules, cascade layers, audit warnings, !important, and the lack of a permanent generated-class API guarantee.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:publishingAnything related to publishing a sitecomplexity:mediumUp to 1 week of workprio:2Always look for prio:1 issues first before working on prio:2type:featFeatures and enhancements

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions