Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v3] Overwriting --ui-* CSS variables does not work with client-side only rendering (ssr: false). #3075

Closed
yschroe opened this issue Jan 12, 2025 · 4 comments
Labels
bug Something isn't working v3 #1289

Comments

@yschroe
Copy link

yschroe commented Jan 12, 2025

Environment

  • Operating System: Linux
  • Node Version: v20.9.0
  • Nuxt Version: 3.15.1
  • CLI Version: 3.17.2
  • Nitro Version: 2.10.4
  • Package Manager: [email protected]
  • Builder: -
  • User Config: default
  • Runtime Modules: @nuxt/[email protected]
  • Build Modules: -

Is this bug related to Nuxt or Vue?

Nuxt

Version

v3.0.0-alpha.10

Reproduction

https://codesandbox.io/p/devbox/keen-chaplygin-lyj8jq

Description

If in nuxt.config.ts the ssr property is set to false, the --ui-* variables cannot be overwritten anymore in :root as described in the nuxt docs here in the green info box: https://ui3.nuxt.dev/getting-started/theme#color-shades.

Only if !important is used, the changes take effect.

I believe this is because the main.css is imported before the variable declaration done by nuxt/ui, so the variable values in main.css are overwritten again. In the final html the --ui-* variable declaration done by nuxt/ui is inlined as the last element in the <head> of the html.

main.css

@import "tailwindcss";
@import "@nuxt/ui";

:root {
  /* Try to use different shade. */
  --ui-primary: var(--ui-color-primary-700); /* Does not work. */
  --ui-success: var(--ui-color-success-700) !important;
}

nuxt.config.ts

export default defineNuxtConfig({
  devtools: { enabled: true },
  modules: ["@nuxt/ui"],
  css: ["~/assets/css/main.css"],
  compatibilityDate: "2025-01-06",
  ssr: false, // works if set to true
});

app.vue

<template>
  <UApp>
    <div class="flex flex-col items-start gap-2">
      <UBadge label="Uses default -500 shade" color="primary" />
      <UBadge label="Uses -700 shade due to !important" color="success" />
    </div>
  </UApp>
</template>
@yschroe yschroe added bug Something isn't working triage v3 #1289 labels Jan 12, 2025
@HugoRCD
Copy link
Collaborator

HugoRCD commented Jan 12, 2025

@yschroe I think by looking at color.ts, the issue might be because of how the plugin injects CSS variables using useHead():

The plugin generates CSS variables and injects them with useHead():

useHead({
  style: [{
    innerHTML: () => root.value,
    tagPriority: -2,
    id: 'nuxt-ui-colors'
  }]
})

With ssr: true, variables are injected during server rendering as part of the initial HTML, so CSS cascade works normally.

With ssr: false, the plugin runs client-side and injects styles after your CSS is processed, requiring !important to override:

--ui-success: var(--ui-color-success-700)         /* Works in SSR */
--ui-success: var(--ui-color-success-700) !important  /* Required without SSR */

@yschroe
Copy link
Author

yschroe commented Jan 12, 2025

@HugoRCD Thanks for looking into it. Is using !important the recommended way to override the variables with ssr: false or can this be fixed in the Nuxt UI module somehow, e.g. by changing the order of the style imports?

Another solution that works for both rendering modes would be to instead override the --ui-* variables on the body tag instead of :root. Due to the higher specifity the overrides on body take precedence over the definitions from Nuxt UI on :root level.

@HugoRCD
Copy link
Collaborator

HugoRCD commented Jan 12, 2025

@yschroe As far as I know, there is no recommended way to manage ssr: false, but I will discuss it to potentially find a solution or document a procedure to follow in this case!

@benjamincanac
Copy link
Member

The @nuxt/ui CSS variables have been moved into the base layer which fixes the priority. However, you won't be able to only override the :root one because it will also apply to .dark, you will need to override both :root and .dark.

@benjamincanac benjamincanac removed the triage label Jan 25, 2025 — with Volta.net
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working v3 #1289
Projects
None yet
Development

No branches or pull requests

3 participants