Tailwind CSS v4 Color Converter
Tailwind CSS v4 defines its entire built-in palette in OKLCH.1
Every default color in the Tailwind v4 design system, from slate-50 to red-950, is stored as an oklch() value rather than HEX. This shift makes the palette perceptually uniform so that equal steps in the lightness scale look equally spaced to the human eye across all hue families. Extending the theme with a custom brand color means expressing it in OKLCH to stay consistent with the rest of the palette, which requires converting from whatever format the brand color is currently stored in.
OKLCH in Tailwind v4 configuration
Tailwind v4 configuration uses CSS custom properties instead of a JavaScript config file. Custom colors are defined in a @theme block in the CSS entry point: @theme { --color-brand: oklch(0.960 0.241 128.2); }.2 Building on this, the three OKLCH coordinates (lightness, chroma, hue) map directly to how the Tailwind palette was constructed, so a brand color expressed in OKLCH sits naturally alongside slate-600 or blue-400 without lightness inconsistency when used at the same numeric level. This tool converts any HEX, RGB, or HSL value to the oklch() coordinate needed for this block, returning coordinates that match the scale Tailwind uses internally.
Choosing the right lightness level
Tailwind v4 lightness values follow a consistent scale: -50 variants sit around L 0.97, -100 at 0.93, -500 at 0.55–0.65, and -900 at 0.20–0.25.3 Knowing your brand color's OKLCH lightness lets you choose the scale step it most closely matches, ensuring the color integrates visually with the system rather than standing out as an inconsistency. Generating a full custom palette for a brand hue, brand-50 through brand-950, requires holding H and C roughly constant while stepping L through the same range Tailwind uses for built-in palettes. Matching the built-in scale positions your custom colors so they sit comfortably next to default Tailwind tokens in a shared UI.
Compatibility and fallbacks
Tailwind v4 generates CSS that uses oklch() in production. All modern browsers support oklch() natively, including Chrome 111+, Firefox 113+, Safari 15.4+, and Edge 111+, covering over 90% of global browser usage.4 Internet Explorer and some older iOS WebViews do not support oklch(), so if your audience includes those browsers the CSS output needs HEX fallbacks inserted before each oklch() declaration. Converting OKLCH to HEX using this tool gives you the fallback value to pair with each custom token. The PostCSS plugin postcss-oklch can automate this fallback insertion at build time, emitting both oklch() and HEX declarations from the same source token so older browsers fall back gracefully.
Understanding the Tailwind v4 OKLCH palette structure
Tailwind v4 organizes its built-in palette on a 0 to 1000 scale where 50 is the lightest and 950 is the darkest. Each step is defined as an oklch() coordinate, and the lightness values follow a consistent curve across all hues: L sits near 0.97 at step 50, near 0.65 at step 500, and near 0.20 at step 950. This consistency means bg-slate-100 and bg-blue-100 look equally bright, which is the core improvement over the v3 HEX-based palette where lightness varied by hue family.
Mapping a custom color to the Tailwind scale
When you add a brand color to Tailwind v4, its L value determines which shade step it best replaces or supplements. A brand blue at oklch(0.612 0.212 261.5) maps to the 500 level because L=0.612 sits in the 0.55 to 0.65 range that Tailwind assigns to its 500 steps. To build a full brand-50 through brand-950 scale, hold H=261.5 and C=0.212 roughly constant while stepping L from 0.97 down to 0.20, matching the exact L values Tailwind uses for its built-in palettes.
The same mapping works in reverse when you are auditing an existing brand ramp. Pasting each step into the converter shows whether your hand-built scale actually follows the Tailwind L curve or drifts away from it at the light and dark ends. That check is worth doing before you ship, because a custom brand scale that breaks the curve looks fine in isolation but reveals the mismatch the moment it sits next to a default Tailwind shade. Keeping the L steps aligned is what makes the custom palette feel like part of the system rather than a bolt-on.
Defining custom colors in the Tailwind v4 @theme block
Tailwind v4 replaces the JavaScript configuration file with a CSS @theme block. Inside @theme { }, each custom property that follows the --color- naming convention auto-generates utility classes. Writing @theme { --color-brand: oklch(0.612 0.212 261.5); } produces bg-brand, text-brand, border-brand, ring-brand, and every other color-based utility Tailwind generates from that single declaration. The naming is flexible, so --color-accent-warm produces bg-accent-warm, text-accent-warm, and so on following the same auto-generation pattern that Tailwind applies to every token defined inside @theme.
Overriding built-in palette entries
Overriding built-in Tailwind colors lets you repurpose any default shade by redefining its custom property name inside the @theme block, which is the fastest way to adjust a single scale step without rebuilding the entire palette. Setting --color-blue-500: oklch(0.65 0.18 250) in the @theme block replaces Tailwind's default blue-500 everywhere it appears. For project-specific extensions that should not collide with built-in names, use a new prefix like --color-product-500 or --color-client-primary.
Adding opacity support to custom Tailwind v4 colors
Tailwind v4 supports color opacity modifiers (bg-brand/50, text-brand/20) for any color defined as a CSS custom property. Internally, Tailwind uses the CSS Relative Color Syntax to derive an opaque version of the color and then applies the opacity modifier. This works with oklch() values because Tailwind's generated utilities reference the custom property through color-mix() or relative color expressions. Your brand color set in oklch() immediately supports all opacity variants without any additional configuration.
Combining opacity with dark mode via @custom-variant
Tailwind v4 defines dark mode through a @custom-variant directive in CSS. The dark variant swaps all color tokens to their dark-mode equivalents when the data-theme attribute or prefers-color-scheme media query activates. Custom brand colors defined in @theme automatically participate in the dark mode switch if you also define dark-mode overrides: @theme { --color-brand: oklch(0.612 0.212 261.5); } and @variant dark { --color-brand: oklch(0.75 0.18 261.5); }.5 The dark variant raises L from 0.612 to 0.75 for better readability on dark backgrounds.
When to use this
Use this when adding a brand color to a Tailwind v4 theme and you need the oklch() coordinate to stay consistent with the perceptually uniform Tailwind v4 palette.
Examples
Brand HEX → Tailwind v4 @theme variable
#c8ff00
oklch(0.960 0.241 128.2)
@theme { --color-brand: oklch(0.960 0.241 128.2); }
Primary HEX → OKLCH scale baseline
#3b82f6
oklch(0.612 0.212 261.5)
Use L=0.612 to map to the "500" level; step L up to 0.97 for "-50".
- 1.
Adam Wathan, "Tailwind CSS v4.0," tailwindcss.com, January 2025. https://tailwindcss.com/blog/tailwindcss-v4
- 2.
Tailwind CSS, "Theme Variables," tailwindcss.com, accessed June 2026. https://tailwindcss.com/docs/theme
- 3.
Tailwind Labs, "colors.ts," github.com, accessed June 2026. https://github.com/tailwindlabs/tailwindcss/blob/main/packages/tailwindcss/src/compat/colors.ts
- 4.
Mozilla Developer Network, "oklch() CSS function," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/color_value/oklch
- 5.
Tailwind Labs, "Allow variants to be overridden," github.com, 2024. https://github.com/tailwindlabs/tailwindcss/pull/14008