DaisyUI Theming with OKLCH Colors

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.

References