Contents

Class Definitions

This is this widget's live class catalog. Composer and Preview read these draft declaration blocks. Publish to send them with the published (and dev.) embed. A new widget starts as a snapshot of the project catalog; edits here stay on this widget.

Class names already travel. This catalog says what they mean

Widgets can already carry CSS class names on columns, rows, and the widget itself. Those names are a contract with the host stylesheet: rounded-xl, px-4, ring-parity-accent/30. RuleCMS does not invent those utilities. Until now it also did not define them.

Class definitions are the missing catalog: a map of class name → CSS declaration block. Fill it on this widget. Composer and Preview apply those rules; publish to send them with the embed — even when the host never compiled that Tailwind pane.

This is the sibling of CSS Variables. Tokens are --name: value. Class definitions are .name { declaration-list }. They are independent toggles: a host that already ships Tailwind can turn class inclusion off and still include CSS variables, or the reverse.

Where this is really useful

You wantClass names onlyClass names plus this catalog
A widget that looks like a host Tailwind gallery even on a page that did not compile those utilitiesClasses are present. Nothing paints unless the host CSS already defines them.RuleCMS ships the declaration blocks with the widget. The embed matches Preview.
Multi-line Tailwind bodies — @supports, color-mix(), shadow/ring custom propertiesImpossible to reconstruct from the class name alone.Paste the declaration list. Nested at-rules and var() are allowed.
A host that already has the same utilitiesWorks today. Do not double-define.Turn published inclusion off. Composer and Preview still use the catalog.
The full widget catalog is included — not “only classes this widget uses.” Same choice as CSS variables. Tree-shaking a utility catalog is easy to get wrong once values nest var() and @supports.

This widget's catalog

Open the widget, then CSS Settings, then Class Definitions. This catalog belongs to this widget.

To change the template for the next widget you create, edit the project catalog.

  • Preview dumps the catalog as .name { … } blocks — the same shape as a Tailwind utilities pane, not :root.
  • Edit is a name plus a textarea for the declaration body. Invalid names and bodies are refused per row. Catalog Save is explicit.

Each entry is one class:

.rounded-xl {
  border-radius: var(--radius-xl);
}

.ring-parity-accent\/30 {
  --tw-ring-color: color-mix(in srgb, #6d28d9 30%, transparent);
  @supports (color: color-mix(in lab, red, red)) {
    --tw-ring-color: color-mix(in oklab, var(--color-parity-accent) 30%, transparent);
  }
}

Names are stored without a leading .. Paste from DevTools with a dot and RuleCMS strips one. Tailwind extras are allowed: /, :, [, ], %, ., _, -. On emit,/ is CSS-escaped so the selector is .ring-parity-accent\/30.

Values are a CSS declaration list, not a single token value. Semicolons, braces, @supports, calc(), var(), and color-mix() are allowed. A value must stay brace-balanced so it cannot close the wrapping rule and inject a new selector. @import, <script, and similar breakouts are rejected. At most 500 classes; 4000 characters per body.

What the renderer does with the catalog

Composer and Preview read this widget's draft catalog. The published embed and the Development (dev.) draft GET read the published widget's catalog. Publish is how a draft catalog goes live.

A new widget starts as a copy of the project catalog. After that, edits here do not write back to the project, and later project edits do not come back here.

SurfaceWhat happens
Composer canvas and PreviewAlways inject from this widget's draft catalog when it is non-empty. The published-inclusion flag is ignored here so authors still see the result while they work.
Published widget (React SDK and HTML custom element)The widget fetch includes this widget's catalog when inclusion is on. Nested collections inherit. You do not get a copy per collection.

When the widget catalog is applied, the renderer emits descendant class rules — .rulecms-render-surface .className { … } in composer, or one scoped <style> under the published-key span on the embed. Nested collections inherit. You do not get a copy per collection.

Turn off inclusion on published widgets

On this widget's Class Definitions page, the Published widgets accordion holds two radios. These radios control whether this widget's published and dev. embed carry the definitions. Composer and Preview still use this widget's catalog when inclusion is off. Changing a radio saves immediately. Catalog Save is separate.

  • Include these class definitions when published widgets are rendered. A non-empty catalog is sent with the widget and the renderer defines the classes inside the widget. This is the default.
  • My apps already have these CSS classes. Do not include them again when the widget is being rendered. Published widgets still carry the class names on elements, but RuleCMS does not ship the declaration blocks. Your host stylesheet must define them.
Composer and Preview still use this widget's catalog when inclusion is off. Only the published (and Development-draft) embed on your site stops carrying the extra rules. CSS variables have their own, independent toggle.
If you turn inclusion off, the host must define every class the widgets use. A missing utility on the live page paints as nothing. Check the published widget on a real route after you flip the setting.

How a published widget receives the catalog

Hosts already fetch the widget once. RuleCMS hangs the catalog on that same response as a sibling of the widget, its collections, and CSS variables — not folded into itemList.

{
  "success": true,
  "data": {
    "widget": { "publishedKey": "…", "itemList": "…", "…": "…" },
    "childCollections": { },
    "cssVariables": { "--radius-xl": "0.75rem" },
    "classDefinitions": {
      "rounded-xl": "border-radius: var(--radius-xl);"
    }
  }
}

classDefinitions is omitted when the catalog is empty, when inclusion is off, or if the catalog cannot be read. When inclusion is off, the same response also sends includeClassDefinitions: false so renderers that still receive a map must not emit it. Missing on the payload means include (legacy clients). The widget still loads.

The React renderer (@rulecms/widget-react) and the HTML custom element turn a non-empty catalog into one <style> scoped to that widget's published key, for example:

[data-rulecms-published-key="env---widget-abc"] .rounded-xl {
  border-radius: var(--radius-xl);
}

Good to know

  • This is not “compile Tailwind inside RuleCMS.” You paste declaration blocks you already have. RuleCMS stores and emits them.
  • Attaching a class name is still a different control. See CSS Classes. This catalog is what those names mean.
  • This catalog belongs to this widget. Copy and promote copy these columns as-is. The project catalog is only the starting snapshot.
  • Leave the catalog empty if the host owns every class. Names on elements still work. Nothing extra is sent to the published page.

Related docs

  • CSS Variables — the token catalog; independent inclusion toggle
  • Fonts — the typeface catalog; class bodies cannot register a face
  • Keyframes — named @keyframes so animation: fade-in … actually runs
  • Position try — named @position-try so position-try-fallbacks: --flip actually registers; built-ins such as flip-block stay in these class bodies
  • Themes — host-dark / color-scheme token overrides; a class can nest @media, a token cannot
  • CSS Properties — typed @property so tokens those classes transition can interpolate
  • Cascade layers — wrap these class rules in @layer utilities or @layer components so they compete with host Tailwind
  • Widget chrome — color-scheme and selection on the widget root; a class can nest ::selection if you put it on every root box
  • CSS Classes — putting names on columns, rows, and widgets
  • HTML Custom Element Embed
  • Development Integration
  • API Reference — the public widget GET, including classDefinitions