[v4] Custom `--ui-*` CSS variable overrides in `@layer base` are silently reverted by `@layer theme` after view transitions / color-mode re-application
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6.9k
- Forks
- 1.1k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 57
Description
Environment
- Operating System: macOS
- Nuxt Version: 4.3.1
- Nuxt UI Version: 4.5.1
- Color Mode:
@nuxtjs/color-modewithpreference: "dark" - Experimental:
viewTransition: true
Reproduction
- In main.css, override
--ui-bgwith a semi-transparent value inside@layer base:
@layer base {
.dark {
--ui-bg: rgba(11, 16, 33, 0.82);
}
}
- Enable view transitions in nuxt.config.ts:
experimental: {
viewTransition: true,
}
- Load the page, the transparent background works correctly.
- Navigate to another page and back, OR trigger a component re-render that causes
@nuxtjs/color-modeto re-apply the.darkclass.
Description
Custom --ui-* CSS variable overrides placed in @layer base (as one would naturally do following Tailwind/CSS conventions) are silently overridden by Nuxt UI's own .dark declarations in @layer theme.
This creates a particularly confusing bug:
- On initial load, the custom values appear to work correctly (e.g.,
--ui-bg: rgba(11, 16, 33, 0.82)renders translucent card backgrounds). - After a view transition (page navigation) or any event that causes
@nuxtjs/color-modeto re-apply the.darkclass, the values revert to Nuxt UI's opaque defaults from@layer theme(e.g.,--ui-bgbecomesoklch(20.8% 0.042 265.755)).
This happens because CSS @layer theme always takes precedence over @layer base in the cascade, regardless of selector specificity. Since Nuxt UI defines its .dark { --ui-bg: var(--ui-color-neutral-900); } in @layer theme, any user customization in @layer base will lose.
Workaround: Move custom --ui-* overrides outside of any @layer (unlayered CSS always wins over layered CSS):
/* Outside any @layer — wins over @layer theme */
.dark {
--ui-bg: rgba(11, 16, 33, 0.82);
}
This is non-obvious (and undocumented?)
Expected behavior
Custom --ui-* variable overrides in @layer base should reliably persist across view transitions, color-mode re-applications, and component re-renders — or the documentation should clearly state which layer/approach to use for overrides.
Suggested fixes
- Documentation: Clearly document that
--ui-*theme variables live in@layer theme, so user overrides in@layer basewill not persist. Recommend unlayered CSS or a specific override pattern. - API improvement: Provide a supported mechanism (e.g., via
app.config.tsor a composable) to override--ui-bgand similar semantic variables without CSS layer conflicts.
Related issues
- #3075 — Same root cause (
@layerordering prevents--ui-*overrides), manifested withssr: false - #3914 — Feature request for a runtime API to override CSS variables
- #4218 — Can't override
--ui-borderdefault color (same family of issues)
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 with the main.css reproduction and nuxt.config.ts settings for viewTransition and color mode, then review the related issues #3075, #3914, and #4218. Confirm that the override changes after navigation or color-mode re-application, and establish whether the accepted fix is documentation of the supported CSS pattern or an API improvement that keeps overrides persistent.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, nuxt, tailwindcss, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100