Using DaisyUI Colors for Dark Mode: Semantic Variables and Theme Configuration
DaisyUI v5 semantic color utilities automatically adapt to light and dark themes through CSS variables, eliminating the need for dark: modifiers in your markup.
DaisyUI v5 (saadeghi/daisyui) revolutionizes dark mode implementation by using semantic color names that resolve to different values based on the active theme. Instead of duplicating classes with dark: prefixes, you use a single set of utilities like bg-primary or text-base-content that automatically switch values when the theme changes.
How Semantic Colors Work in DaisyUI
DaisyUI generates semantic color utilities backed by CSS variables defined in packages/daisyui/functions/variables.js. Each color name—such as primary, base-100, or neutral—maps to a CSS custom property like --color-primary or --color-base-100.
When you apply a utility class like bg-primary or text-base-content, the browser references these variables. As the active theme switches from light to dark, the underlying variable values update automatically, rendering the appropriate color without changing your HTML classes.
Enabling Automatic Dark Mode Detection
The default DaisyUI configuration enables seamless dark mode through the --prefersdark flag. In packages/daisyui/functions/themePlugin.js, this flag triggers the addition of a @media (prefers-color-scheme: dark) rule that applies the dark theme's variables to the appropriate root element.
Configure your themes in your CSS file:
@plugin "daisyui" {
themes: light --default, dark --prefersdark;
}
light --defaultsets the light theme as the initial appearancedark --prefersdarkdesignates the dark theme as the fallback when the user's OS prefers dark color schemes
Practical Implementation Examples
Basic Usage Without Dark Prefixes
Because colors are tied to CSS variables, you never duplicate class names for light and dark variants:
<div class="p-10 bg-base-200 rounded-2xl">
<div class="p-6 bg-base-100 border-2 border-base-300 text-base-content rounded-lg">
This text adapts automatically: dark on light backgrounds, light on dark backgrounds.
</div>
</div>
Explicit Theme Selection
Force a specific theme using the data-theme attribute:
<html data-theme="dark">
<button class="btn btn-primary">Primary button</button>
</html>
Custom Dark Themes
Create custom dark themes by specifying them in your configuration:
@plugin "daisyui" {
themes: winter --default, night --prefersdark;
}
When the night theme is active, all semantic utilities automatically resolve to that theme's color values.
Overriding Colors in Dark Mode
Customize specific colors for your dark theme using the theme override syntax:
@plugin "daisyui" {
themes: light --default, dark --prefersdark;
}
@plugin "daisyui/theme" {
name: "dark";
"primary": "#0ea5e9";
}
This merges your custom primary color with the built-in dark theme, as handled by the merge logic in packages/daisyui/functions/themePlugin.js.
Using Opacity with Semantic Colors
Opacity modifiers work transparently across both themes:
<div class="bg-primary/50">50% opaque primary background</div>
Creating Custom Dark Themes
When building custom themes, add them to the themes list and flag them with --prefersdark to enable automatic OS detection. The plugin merges custom tokens with built-in themes, so you only override the specific colors you need.
For advanced use cases combining DaisyUI with Tailwind's dark: variant, configure a custom variant that targets your specific dark theme:
@plugin "daisyui" {
themes: winter --default, night --prefersdark;
}
@custom-variant dark (&:where([data-theme=night], [data-theme=night] *));
<div class="p-10 dark:p-20">
Padding doubles only when the night theme is active.
</div>
Summary
- DaisyUI v5 uses semantic color names (primary, base-100, base-content) backed by CSS variables defined in
packages/daisyui/functions/variables.js - The
--prefersdarkflag in your theme configuration enables automatic dark mode detection viaprefers-color-schememedia queries, implemented inpackages/daisyui/functions/themePlugin.js - No
dark:prefixes are required because utilities likebg-primaryautomatically resolve to theme-specific values - Custom themes merge with built-in themes, allowing targeted color overrides without redefining the entire palette
- Opacity modifiers (e.g.,
bg-primary/50) work consistently across light and dark themes
Frequently Asked Questions
Do I need to use dark: prefixes with DaisyUI?
No. DaisyUI's semantic color system eliminates the need for dark: prefixes because each utility class references CSS variables that change values based on the active theme. When the dark theme is active, bg-base-100 automatically renders a dark background, and text-base-content automatically renders light text.
How does DaisyUI detect the user's OS dark mode preference?
DaisyUI detects OS preferences through the --prefersdark flag in your theme configuration. According to the packages/daisyui/functions/themePlugin.js implementation, this flag generates a @media (prefers-color-scheme: dark) rule that applies the dark theme's CSS variables to :root when the user's system is set to dark mode.
Can I create a custom dark theme with specific brand colors?
Yes. Define your custom theme using the @plugin "daisyui/theme" syntax and specify the colors you want to override. The plugin merges your custom tokens with the built-in theme structure, so you only need to define the specific color values you want to change, such as setting "primary": "#0ea5e9" for a custom dark primary color.
What is the difference between base-100 and base-content?
base-100 represents the page background color (the dominant surface), while base-content represents the text color designed to contrast against that background. In a light theme, base-100 is typically white or light gray and base-content is dark gray or black. In a dark theme, these values invert automatically, with base-100 becoming dark and base-content becoming light.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →