Feature: introduce `--ui-bg-body` to decouple body background from the component surface scale
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6.9k
- Forks
- 1.1k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 57
Description
Feature Request — Decouple body background from --ui-bg / introduce --ui-bg-body
Summary
The framework currently uses --ui-bg (via bg-default) for both the <body> background and as the base of the component background scale. This coupling makes two common customisations unnecessarily hard:
- Setting a slightly different body background (e.g. a warm off-white, a subtle tint) while keeping component surfaces white.
- Scaling the entire background palette coherently when
--ui-bgis overridden.
Current behaviour
The framework applies bg-default (= --ui-bg) to the <body> element in its base styles:
/* Nuxt UI internals */
body {
@apply antialiased text-default bg-default scheme-light dark:scheme-dark;
}
The background scale in light mode is:
| Variable | Default value |
|---|---|
--ui-bg |
white |
--ui-bg-muted |
var(--ui-color-neutral-50) |
--ui-bg-elevated |
var(--ui-color-neutral-100) |
--ui-bg-accented |
var(--ui-color-neutral-200) |
--ui-bg-inverted |
var(--ui-color-neutral-900) |
Problem 1 — Body and component surfaces are coupled
A very common design pattern is: body has a slightly tinted/off-white background, while cards and panels sit on a pure white surface so they "lift" off the page.
Right now this is impossible without overriding the body styles manually, because --ui-bg drives both:
- the page/body background
bg-defaultused by all surface components (UCard,UPageCard, etc.)
Developers currently resort to fighting the framework:
/* Workaround — override body manually */
body {
background-color: var(--my-custom-body-bg);
}
This breaks out of the design token system entirely.
Proposed fix: Introduce a dedicated --ui-bg-body variable (defaulting to --ui-bg for full backward compatibility) and apply it to <body> instead:
/* Proposed */
:root {
--ui-bg-body: var(--ui-bg); /* override this independently */
}
body {
@apply antialiased text-default scheme-light dark:scheme-dark;
background-color: var(--ui-bg-body);
}
This would let developers do:
:root {
--ui-bg-body: var(--ui-color-neutral-50); /* subtle warm/tinted page bg */
/* --ui-bg stays white → all cards/panels remain white, floating on top */
}
Problem 2 — Overriding --ui-bg does not shift the rest of the scale proportionally
The --ui-bg-muted / elevated / accented variables are hardcoded to fixed neutral stops (50, 100, 200). If a developer overrides --ui-bg to a reddish or tinted value:
:root {
--ui-bg: oklch(97% 0.01 25); /* very light warm/reddish */
}
…the rest of the scale stays in the neutral-grey family. The tint is not carried through, making the overall palette feel incoherent.
Ideally the scale would be expressed in relative steps from --ui-bg, or at minimum the documentation should guide developers on how to consistently shift the full scale when they change the base.
Connection to PageCard variant semantics
This issue is related to #6515 (inconsistent outline / solid variants on PageCard).
With a proper --ui-bg-body separation:
solidPageCard —bg-default(--ui-bg) makes perfect sense: a white card on a tinted page background clearly reads as "solid/elevated".outlinePageCard — transparent background with only a ring is correct: the body tint shows through, distinguishing it from a solid card.
The current inverted/dark solid and the opaque outline make more sense as a workaround for the fact that without body/surface separation there is no visible difference between a transparent card and a bg-default card.
Proposed API
/* Light mode */
:root {
--ui-bg: white; /* component surface base — unchanged */
--ui-bg-body: var(--ui-bg); /* NEW — body background, defaults to --ui-bg */
--ui-bg-muted: var(--ui-color-neutral-50);
--ui-bg-elevated: var(--ui-color-neutral-100);
--ui-bg-accented: var(--ui-color-neutral-200);
--ui-bg-inverted: var(--ui-color-neutral-900);
}
/* Dark mode */
.dark {
--ui-bg: var(--ui-color-neutral-900);
--ui-bg-body: var(--ui-bg); /* same default */
...
}
This is a non-breaking change: all existing projects behave identically (since --ui-bg-body falls back to --ui-bg), but developers who want a different page background now have a clean, first-class token to override.
Environment
@nuxt/uiv4 (latest)- Nuxt 4
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the base styles that apply bg-default to body and the theme definitions for --ui-bg and its related variables. Add --ui-bg-body with the existing --ui-bg value as its default, apply it to body in light and dark modes, and verify that component surfaces remain unchanged when it is overridden independently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, nuxt, tailwindcss
- Domain
- design, frontend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100