Spacing defines a value; Density defines how spacing responds to the viewport. Prefer density(n) for component spacing using the theme’s responsive mapping. Use space(n) directly when a stable value across breakpoints is intentional. Changing that mapping updates every consumer of the token without changing component code.
Density is the recommended default for component spacing. Standard CSS remains available when finer control is needed. The generated media queries belong to the system; they are not removed from CSS.
UXDSL builds on standard CSS. Spacing defines the base spacing values, and Density makes that spacing responsive. Prefer Density for component spacing, use Spacing when a stable value is intentional, and use CSS directly when finer control is needed. This is the recommended authoring approach, not a compiler restriction.
A Density token maps a level to spacing values at different breakpoints. The 4 in density(4) identifies a token; it does not mean four pixels or a multiplier. You define its progression.
This example is a theme excerpt. Density reuses the spacing scale instead of introducing a separate set of measurements.
{
"breakpoints": { "xs": 0, "md": 768, "xl": 1280 },
"spacing": {
"4": "0.75rem",
"5": "1rem",
"6": "1.5rem"
},
"densities": {
"4": "xs(space(4)) md(space(5)) xl(space(6))"
}
}| Viewport | density(4) | space(4) |
|---|---|---|
| Below 768px | space(4) → 0.75rem | 0.75rem |
| 768–1279px | space(5) → 1rem | 0.75rem |
| 1280px and above | space(6) → 1.5rem | 0.75rem |
A rule remains active until another defined breakpoint overrides it. The progression is configurable: spacing can increase, decrease or stay the same.
.card, .panel {
padding: density(4);
}The card and panel choose a token. Its responsive behavior lives in the theme.
/* Base spacing tokens from the theme */
:root {
--uxdsl__space__4: 0.75rem;
--uxdsl__space__5: 1rem;
--uxdsl__space__6: 1.5rem;
--uxdsl__density__4: var(--uxdsl__space__4);
}
@media (min-width: 768px) {
:root { --uxdsl__density__4: var(--uxdsl__space__5); }
}
@media (min-width: 1280px) {
:root { --uxdsl__density__4: var(--uxdsl__space__6); }
}
.card, .panel {
padding: var(--uxdsl__density__4);
}You can build this same behavior in plain CSS using responsive custom properties. UXDSL generates those rules from the theme, so you maintain one mapping instead of repeating breakpoint decisions in each component. Less repeated source code does not necessarily mean less generated CSS.
These live boxes use this page’s current theme and actual browser viewport. The colored area is padding. Edit the active rule for Density 4 to see both responsive boxes change; the fixed box continues to use space(4).
Live density(4): xs(space(4)) md(space(5)) xl(space(6))
padding: density(4)padding: density(4)padding: space(4)Resize your browser to see the responsive boxes follow the mapping. The JSON and CSS above remain a reference example; the live definition shows your edits. Edits are a local demo and are not saved to your theme file.
Two ways to update the system: change a spacing value to update every reference to that spacing token, or change a Density mapping to update every consumer of that Density token. Component declarations stay the same.
Prefer density() for component spacing. Use space() directly for an intentional stable value, or CSS for finer control. A Spacing value remains editable through the theme. Density coordinates spacing; layout changes such as columns and navigation still need their own responsive decisions.
Each ring compares a Density level measured from the same content. The rings are not nested component paddings added together. Click a ring to edit its token. This diagram responds to the main browser viewport.
.any-class {
padding: density(4);
}Update the tokens below to reflect changes in the UI.
AI implementation guide
UXDSL builds on standard CSS. Spacing defines the base spacing values, and Density makes that spacing responsive. Prefer Density for component spacing, use Spacing when a stable value is intentional, and use CSS directly when finer control is needed. This is the recommended authoring approach, not a compiler restriction.
When generating or modifying UI with UXDSL:
spacing, densities, and breakpoints definitions before selecting spacing tokens.density(n) token by default for component spacing.space(n) directly when a stable value across breakpoints is intentional. Use CSS directly when finer control outside the configured Density behavior is required.density(n) as a reference to a configured responsive spacing token. Never assume density(4) equals space(4) at every breakpoint.Decision rule: Prefer Density for component spacing. Use Spacing for intentional stable values and CSS for finer control. Change shared Spacing or Density definitions only for intentional system-level changes.
Choose the token in the component. Define its responsive behavior in the theme.
Given this example theme excerpt:
{
"breakpoints": {
"xs": 0,
"md": 768,
"xl": 1280
},
"spacing": {
"4": "0.75rem",
"5": "1rem",
"6": "1.5rem"
},
"densities": {
"4": "xs(space(4)) md(space(5)) xl(space(6))"
}
}When a component should follow that configured responsive progression, prefer:
.card {
padding: density(4);
}This resolves according to the theme:
768px → space(4) → 0.75rem.768px up to, but not including, 1280px → space(5) → 1rem.1280px and above → space(6) → 1.5rem.Avoid recreating the same system behavior locally:
.card {
padding: xs(space(4)) md(space(5)) xl(space(6));
}The local form duplicates behavior already represented by density(4) and disconnects the component from future changes to that Density mapping. It still references the spacing scale.
Explicit local responsive spacing is valid when the component intentionally requires behavior that should remain independent from the configured Density mapping.
If asked:
Make this card's padding follow the application's responsive spacing.
The agent should:
padding: density(4).The component declares which responsive spacing token it uses.
The theme defines how that token behaves across breakpoints.