· 5 min read
How to Turn a Light CSS Palette Into Dark Mode
Heshan Fernando
Co-founder & COO
You built a color system for a light interface — a soft off-white background, a navy primary button, a muted gray for secondary text — and now someone’s asking for a dark mode toggle. The lazy fix is to invert everything with a CSS filter, and it looks exactly as bad as you’d expect: blown-out whites turn into a strange gray-blue, and your carefully chosen brand blue turns orange because invert() flips hue along with lightness.
The other lazy fix is starting from scratch, picking new hex codes for every token by eye. That works, but it’s slow, and it’s easy to end up with a dark palette that doesn’t actually match your light one — buttons that were royal blue in light mode become teal in dark mode because nobody wrote down the relationship between the two.
What converting a palette to dark mode actually involves
A light-to-dark conversion isn’t a global invert — it’s a per-color adjustment. The hue (is it blue, is it red) and the saturation (how vivid it is) usually stay close to what they were. What actually needs to flip is lightness: a background that was near-white needs to become near-black, and text that was near-black needs to become near-white, while accent colors get nudged lighter or darker just enough to stay visible on the new background.
Done well, this keeps your brand identifiable — a dark-mode version of your blue button should still read as “your blue,” just adapted for a dark background instead of a light one.
Why people get stuck here
- Hue drift. Naive inversion (
filter: invert(1)) flips hue, not just lightness, so blues become oranges and greens become magentas. - Contrast breaks. A gray that had comfortable contrast against white can become nearly invisible against a near-black background if lightness isn’t recalculated properly.
- Manual palettes drift apart. When someone hand-picks dark-mode colors independently, the light and dark themes stop feeling like the same brand.
- CSS variable sprawl. A real design system might have 20-40 color tokens (background, surface, border, text-primary, text-secondary, accent, accent-hover…), and manually converting each one is tedious and error-prone.
What a good conversion looks like
Lightness gets inverted, hue and saturation don’t
The core operation should preserve what makes each color recognizable — its hue and saturation — and only adjust how light or dark it is. That’s the difference between “dark mode that still looks like your brand” and “dark mode that looks like a different app.”
Output as ready-to-use CSS variables
If your light palette is already CSS custom properties, the dark version should come back the same way — a :root[data-theme="dark"] block (or similar) you can paste straight into your stylesheet, not a list of hex codes you have to wire up yourself.
You can eyeball it before committing
Before you ship a dark theme, you want to see the converted swatches side by side with the originals, so an unexpectedly muddy or oversaturated color doesn’t slip through.
Common mistakes to avoid
- Using a CSS
filter: invert()on the whole page instead of converting the actual color values — it also inverts images and photos, which looks broken. - Forgetting to re-check contrast ratios after conversion; a lightness flip that looks fine to the eye can still fail WCAG AA for body text.
- Converting backgrounds and text separately without checking they still pair correctly (e.g., text ends up only slightly lighter than the new dark background).
- Hardcoding dark-mode hex values instead of keeping them as CSS variables, which makes future brand color changes painful to propagate.
- Assuming one lightness inversion formula works for every color — a saturated accent color often needs a different adjustment than a near-neutral gray.
How to do it with Dark Mode Palette Converter
Online Tool Store’s Dark Mode Palette Converter runs entirely in your browser, so your color values never leave your machine.
- Open the Dark Mode Palette Converter and enter your light-theme colors (hex values or CSS variables).
- Let it invert lightness while preserving each color’s hue and saturation.
- Compare the light and dark swatches side by side before you commit to anything.
- Copy the generated dark-mode CSS variables straight into your stylesheet.
Because it’s a client-side conversion, you can paste in colors that are still work-in-progress or unpublished without worrying about them going anywhere.
Frequently asked questions
Does this replace manual dark-mode design entirely?
For a lot of interfaces, yes — a hue-preserving lightness inversion gets you a usable, on-brand dark theme fast. For a polished product you’ll still want to spot-check contrast on your actual components, since a color that reads fine as a swatch can behave differently next to specific text sizes or icons.
Will my brand colors still look like my brand colors?
That’s the point of preserving hue and saturation instead of doing a straight inversion. Your blue stays blue in dark mode; it just gets adjusted in lightness so it doesn’t glow or disappear against a dark background.
Can I convert individual colors, or does it need a full palette?
You can run a single color through if that’s all you need, but the tool is most useful when you feed it a whole set of tokens at once, so the relationships between background, text, and accent colors stay consistent.
Final thought
A dark theme that’s actually a dark theme — not just an inverted screenshot — comes down to changing lightness while leaving hue and saturation alone. Do that consistently across your token set and the two themes will feel like the same product in two different lights.