Copied utilities fight the host Tailwind pane
Tailwind is layers — base, components, utilities. RuleCMS Class Definitions emit as unlayered [data-rulecms-published-key] .name rules. The same utility can steamroll the host or lose to it depending on which stylesheet loads last. A class body cannot contain a top-level @layer.
Cascade layers is a setting for how those class definitions are emitted. It is not a second stylesheet and it does not compile Tailwind. You pick utilities or components. RuleCMS wraps the existing class sheet.
When to use it / when not to
| You want | Leave unlayered | Wrap in a layer |
|---|---|---|
| Copied utilities to compete with host Tailwind the same way Tailwind utilities do | Unlayered rules win or lose by stylesheet order. A later host sheet can override them — or they can override the host. | Pick utilities. Class rules sit in @layer utilities and compete with the host pane. |
| Component-style classes that should sit under host utilities | They fight utilities as unlayered CSS. | Pick components. Host utilities still win the cascade the way Tailwind intends. |
| A host that already puts these class names in a layer | Works today. Do not wrap them again. | Turn published inclusion off. Composer and Preview still wrap when the setting is defined. |
utilities vs components. Use utilities for copied Tailwind utilities. Use components when the classes should lose to host utilities. There is no free-text layer name and no @layer reset, theme, utilities list.This widget's catalog
Open the widget, then CSS Settings, then Cascade layers. This catalog belongs to this widget.
To change the template for the next widget you create, edit the project catalog.
- Preview shows a short example using
.rounded-xl— wrapped or unlayered — not a pasted stylesheet editor. - Edit is one select: Do not wrap (default),
utilities, orcomponents. Saving “do not wrap” deletes the setting. Catalog Save is explicit.
A typical wrapped emit looks like this:
@layer utilities {
[data-rulecms-published-key="env---w"] .rounded-xl {
border-radius: var(--radius-xl);
}
}Empty or omitted is today's unlayered class emit. This setting never styles :root, html, or 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.
| Surface | What happens |
|---|---|
| Composer canvas and Preview | Always 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 setting is applied and a layer is set, the class stylesheet is wrapped. When inclusion is off on the published embed, classes still emit — unlayered — even if a layer is saved. If there are no class definitions, nothing is emitted.
Published widgets
On this widget's Cascade layers 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 this cascade layer wrapper when published widgets are rendered. A saved layer wraps the class stylesheet. This is the default.
- My apps already put these utilities in a layer. Do not wrap them again when the widget is being rendered. Published widgets still carry class definitions, but RuleCMS does not wrap them. Your host stylesheet already owns cascade.
How a published widget receives the setting
Hosts already fetch the widget once. RuleCMS hangs the setting on that same response as a sibling of the widget and its class definitions — not folded into itemList. The fields are classLayer and, when wrapping is off, includeClassLayer: false.
{
"success": true,
"data": {
"widget": { "publishedKey": "…", "itemList": "…", "…": "…" },
"childCollections": { },
"classDefinitions": {
"rounded-xl": "border-radius: var(--radius-xl);"
},
"classLayer": "utilities"
}
}classLayer is omitted when the setting is empty, when inclusion is off, or if the catalog cannot be read. When inclusion is off, the same response also sends includeClassLayer: false so renderers that still receive a layer name must not wrap. Missing on the payload means include (legacy clients). The widget still loads.
The React renderer (@rulecms/widget-react) and the HTML custom element wrap the existing class stylesheet, for example:
@layer utilities {
[data-rulecms-published-key="env---w"] .rounded-xl {
border-radius: var(--radius-xl);
}
}Good to know
- This catalog belongs to this widget. Copy and promote copy these columns as-is. The project catalog is only the starting snapshot.
- At most one layer entry. This is a single select, not a list.
- This is not generic
@layerauthoring. You cannot name a layerresetor write a layer-order list. - React and the HTML embed this pass. Other framework SDKs do not wrap class emit yet.
- Leave the setting empty if unlayered emit is what you want. Class names still work. Nothing extra is sent.
Related docs
- Class Definitions — the utility catalog this setting wraps
- CSS Variables — tokens those classes can point at
- Fonts — the typeface catalog
- Keyframes — named
@keyframes - Position try — named
@position-tryfallbacks - Themes — host-dark token overrides
- CSS Properties — typed
@property - Widget chrome — color-scheme and selection on the widget root
- HTML Custom Element Embed
- Development Integration
- API Reference — the public widget GET, including
classLayer - Projects, Environments & Tokens
- The Composer