TL;DR
DaisyUI v5 uses OKLCH color space for themes. Override --color-* variables in CSS. OKLCH gives perceptually uniform colors - same lightness value means same perceived brightness.
The Problem
You want a custom dark theme for DaisyUI. The built-in themes are close but not right. You need:
- Dark background that doesn’t feel washed out
- Vibrant accent colors that pop
- Consistent perceived brightness across your palette
Why OKLCH?
HSL and RGB are mathematically convenient but perceptually uneven. Blue at 50% lightness looks darker than yellow at 50% lightness.
OKLCH fixes this. It has three channels:
- L (Lightness): 0% = black, 100% = white. Perceptually uniform.
- C (Chroma): Color intensity. 0 = gray, higher = more saturated.
- H (Hue): Color angle. 0/360 = red, 120 = green, 240 = blue.
Same L value across colors? Same perceived brightness.
DaisyUI v5 Theme Variables
DaisyUI v5 uses CSS custom properties for theming:
@layer base {
:root {
/* Base backgrounds */
--color-base-100: oklch(18% 0.03 270);
--color-base-200: oklch(15% 0.025 270);
--color-base-300: oklch(12% 0.02 270);
--color-base-content: oklch(91% 0.01 270);
/* Primary - your main brand color */
--color-primary: oklch(78% 0.18 60);
--color-primary-content: oklch(15% 0.02 60);
/* Secondary */
--color-secondary: oklch(73% 0.12 270);
--color-secondary-content: oklch(15% 0.02 270);
/* Accent */
--color-accent: oklch(73% 0.1 320);
--color-accent-content: oklch(15% 0.02 320);
}
}
Naming Convention
--color-{name}: The color itself--color-{name}-content: Text/foreground on that color
DaisyUI components use these automatically. A .btn-primary gets --color-primary background with --color-primary-content text.
Building a Dark Theme
1. Choose Your Hues
Pick 3-4 hue angles for your palette:
/* Orange accent: hue 60 */
--color-primary: oklch(78% 0.18 60);
/* Blue: hue 270 */
--color-secondary: oklch(73% 0.12 270);
/* Lavender/Purple: hue 320 */
--color-accent: oklch(73% 0.1 320);
2. Set Base Colors
Dark backgrounds need low lightness with subtle chroma:
/* Main background - very dark blue-ish */
--color-base-100: oklch(18% 0.03 270);
/* Slightly darker for cards/sections */
--color-base-200: oklch(15% 0.025 270);
/* Darkest for borders/dividers */
--color-base-300: oklch(12% 0.02 270);
/* Light text on dark background */
--color-base-content: oklch(91% 0.01 270);
The chroma (0.03) adds warmth. Pure gray would be oklch(18% 0 0).
3. Semantic Colors
Status colors follow the same pattern:
/* Success - green hue ~145 */
--color-success: oklch(70% 0.15 145);
--color-success-content: oklch(15% 0.02 145);
/* Warning - gold hue ~70 */
--color-warning: oklch(75% 0.12 70);
--color-warning-content: oklch(15% 0.02 70);
/* Error - red hue ~25 */
--color-error: oklch(65% 0.2 25);
--color-error-content: oklch(95% 0.01 25);
Notice error has high chroma (0.2) for urgency. Warning is softer (0.12).
Creating Gradients
OKLCH gradients look better because interpolation is perceptually linear:
.gradient-bar {
background: linear-gradient(
to right,
oklch(78% 0.18 60), /* Orange */
oklch(73% 0.12 270), /* Blue */
oklch(73% 0.1 320) /* Lavender */
);
}
Compare to the same colors in HSL - the OKLCH version has smoother transitions without muddy middle tones.
Adding Custom Colors
Beyond DaisyUI’s semantic colors, add your own:
@theme {
--color-portfolio-orange: oklch(78% 0.18 60);
--color-portfolio-blue: oklch(73% 0.12 270);
--color-portfolio-lavender: oklch(73% 0.1 320);
--color-portfolio-gold: oklch(75% 0.12 70);
}
With Tailwind v4’s @theme directive, these become usable as bg-portfolio-orange, text-portfolio-blue, etc.
Hover States with OKLCH
Create lighter/darker variants by adjusting lightness:
.button {
background: oklch(78% 0.18 60);
}
.button:hover {
background: oklch(82% 0.18 60); /* +4% lightness */
}
.button:active {
background: oklch(74% 0.18 60); /* -4% lightness */
}
Keep chroma and hue constant. Only change lightness.
Matching Text to Backgrounds
For content colors, use the same hue but extreme lightness:
/* Dark background, light text */
--color-primary: oklch(78% 0.18 60);
--color-primary-content: oklch(15% 0.02 60);
/* Light background, dark text */
--color-accent: oklch(73% 0.1 320);
--color-accent-content: oklch(15% 0.02 320);
Low chroma on content (0.02) keeps text readable while maintaining color harmony.
Debugging OKLCH
Chrome DevTools shows OKLCH in the color picker. Click a color swatch and switch to OKLCH mode.
Quick reference for hues:
- 0/360: Red
- 30: Orange
- 60: Yellow
- 120: Green
- 180: Cyan
- 240: Blue
- 300: Magenta
- 320: Purple/Lavender
Browser Support
OKLCH is supported in all modern browsers (Chrome 111+, Safari 15.4+, Firefox 113+). No fallback needed unless supporting IE11 or very old mobile browsers.