admin管理员组

文章数量:1410717

I'm trying to set up a custom theme in Tailwind CSS v4 that auto-switches to dark mode without adding the dark: prefix to every custom class.

In Tailwind v3, my setup was:

  • index.css:

    :root {
        --color-primary100: #0A7280;
        --color-primary50: #BAD7DB;
        --color-bgBase: #FDFDFD;
    }
    
  • tailwind.config.js:

    export default {
        darkMode: 'class',
        content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
        plugins: [tailwindCssForms, containerQueries],
        theme: {
            extend: {
                colors: {
                    primary100: "var(--color-primary100, #0A7280)",
                    primary50: "var(--color-primary50, #BAD7DB)",
                    bgBase: "var(--color-bgBase, #FDFDFD)",
                },
            },
        },
    }
    

Toggling the dark mode by adding a dark class to <html> worked as expected without having to set a dark:bg-primary100-V2 bg-primary100 everywhere :

A single bg-primary100 will handle it both themes (multiply it by each customized props and you see why this is important)

After migrating to Tailwind CSS v4 (), I updated my CSS using the new @theme syntax :

@import 'tailwindcss';
@plugin '@tailwindcss/forms';
@plugin '@tailwindcss/container-queries';

@custom-variant dark (&:where(.dark, .dark *));

@theme {
  --color-bgContrast: #f9f9f9;
}

/*and was hopping for this to do the job but i tried many others */
@theme dark: {
  --color-bgContrast: #66C8B6;
}

I expected that adding <html class="dark"> would update --color-bgContrast to #66C8B6, but it doesn't work as intended. My goal is to avoid duplicating styles with multiple dark: prefixes across components everywhere.

Has anyone managed to achieve this centralized dark theme approach in v4 or faced a similar issue? Any insights or workarounds would be appreciated.

I'm trying to set up a custom theme in Tailwind CSS v4 that auto-switches to dark mode without adding the dark: prefix to every custom class.

In Tailwind v3, my setup was:

  • index.css:

    :root {
        --color-primary100: #0A7280;
        --color-primary50: #BAD7DB;
        --color-bgBase: #FDFDFD;
    }
    
  • tailwind.config.js:

    export default {
        darkMode: 'class',
        content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
        plugins: [tailwindCssForms, containerQueries],
        theme: {
            extend: {
                colors: {
                    primary100: "var(--color-primary100, #0A7280)",
                    primary50: "var(--color-primary50, #BAD7DB)",
                    bgBase: "var(--color-bgBase, #FDFDFD)",
                },
            },
        },
    }
    

Toggling the dark mode by adding a dark class to <html> worked as expected without having to set a dark:bg-primary100-V2 bg-primary100 everywhere :

A single bg-primary100 will handle it both themes (multiply it by each customized props and you see why this is important)

After migrating to Tailwind CSS v4 (https://tailwindcss/docs/dark-mode), I updated my CSS using the new @theme syntax :

@import 'tailwindcss';
@plugin '@tailwindcss/forms';
@plugin '@tailwindcss/container-queries';

@custom-variant dark (&:where(.dark, .dark *));

@theme {
  --color-bgContrast: #f9f9f9;
}

/*and was hopping for this to do the job but i tried many others */
@theme dark: {
  --color-bgContrast: #66C8B6;
}

I expected that adding <html class="dark"> would update --color-bgContrast to #66C8B6, but it doesn't work as intended. My goal is to avoid duplicating styles with multiple dark: prefixes across components everywhere.

Has anyone managed to achieve this centralized dark theme approach in v4 or faced a similar issue? Any insights or workarounds would be appreciated.

Share Improve this question edited Mar 6 at 7:12 rozsazoltan 11.4k6 gold badges21 silver badges60 bronze badges asked Mar 5 at 16:33 pierre.bpierre.b 2313 silver badges10 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

You seem to have used incorrect syntax. To set dark mode color variable values, you could do:

@layer theme {
  .dark {
    --color-bgContrast: #66C8B6;
  }
}
  • Places the rule into the theme CSS cascade layer, where theme token related CSS rules go.
  • The .dark selector selects the HTML elements with the dark class name.
  • We then override the CSS variable values as per CSS grammar.

document.querySelector('button').addEventListener('click', () => {
  document.documentElement.classList.toggle('dark');
});
<script src="https://unpkg/@tailwindcss/[email protected]"></script>

<style type="text/tailwindcss">
@import 'tailwindcss';

@custom-variant dark (&:where(.dark, .dark *));

@theme {
  --color-bgContrast: #f9f9f9;
}

@layer theme {
  .dark {
    --color-bgContrast: #66C8B6;
  }
}
</style>

<button class="grid place-items-center size-20 bg-bgContrast">Toggle</button>

Basically, Wongjn has already answered the question, but I would like to draw attention to the use of @variant dark.

With @variant, you don’t need to update the code if, for example, in the future you no longer want to identify dark mode as .dark. So, if you modify the @custom-variant setting, this will automatically take effect in the @variant.

  • @variant directive - TailwindCSS v4 Docs

document.querySelector('button').addEventListener('click', () => {
  document.documentElement.classList.toggle('dark');
});
<script src="https://unpkg/@tailwindcss/[email protected]"></script>
<style type="text/tailwindcss">
@custom-variant dark (&:where(.dark, .dark *));

@theme {
  --color-bgContrast: #f9f9f9;
}

@layer base {
  @variant dark {
    --color-bgContrast: #66C8B6;
  }
}
</style>

<button class="grid place-items-center size-20 bg-bgContrast">Toggle</button>

And if change rule of dark mode:

document.querySelector('button').addEventListener('click', () => {
  document.documentElement.classList.toggle('new-dark');
});
<script src="https://unpkg/@tailwindcss/[email protected]"></script>
<style type="text/tailwindcss">
/* changed classname from .dark to .new-dark */
@custom-variant dark (&:where(.new-dark, .new-dark *));

@theme {
  --color-bgContrast: #f9f9f9;
}

@layer base {
  /* working without modification */
  @variant dark {
    --color-bgContrast: #66C8B6;
  }
}
</style>

<button class="grid place-items-center size-20 bg-bgContrast">Toggle</button>

本文标签: htmlTailwindCSS v4 dark theme by class not working without dark tagStack Overflow