Dark Mode Color GeneratorContrast Check, CSS Variables

Enter your light theme colors and get a matching dark palette, with a contrast check on every text and accent color and CSS you can copy.

Light mode

Card title

Secondary text sits on the card surface.

Body text with a link.

Dark mode

Card title

Secondary text sits on the card surface.

Body text with a link.

Colors

Light
Darkauto
Light
Darkauto
Light 1.1:1Dark 1.1:1
Light
Darkauto
Light 17.7:1 · AAADark 14.4:1 · AAA
Light
Darkauto
Light 4.8:1 · AADark 5.5:1 · AA
Light
Darkauto
Light 6.3:1 · AADark 4.7:1 · AA
Light
Darkauto
Light 1.2:1Dark 1.4:1
Light
Darkauto
Light 4.8:1 · AADark 6.1:1 · AA

Contrast ratios are measured against the background color of the same mode. For Text and Accent colors the badge shows the WCAG 2 level reached. For Surface, Border, and Other colors only the ratio is shown.

CSS variables

Convert a light palette to dark by role, not by inversion

Flipping every color of a light theme gives a harsh result: bright accents, pure black, and text that is either too faint or too glaring. This tool treats each color by its role in the interface and converts it with a rule suited to that role.

Give each color a name and a role, such as Background, Surface, Text, or Accent. The dark color is generated, and text and accent colors are lightened until they reach a 4.5:1 contrast ratio on the dark background. The preview shows both modes side by side.

You can edit any dark color by hand, then copy the whole palette as CSS variables. Everything runs in your browser.

When you need a dark palette

Adding dark mode to an existing site

Start from the colors you already use for light mode and get a matching dark set to drop into your stylesheet.

Checking a brand color on dark

See how a brand accent looks on a dark background and whether it keeps a readable contrast ratio for links and buttons.

Planning surface levels

Add several Surface rows to get lighter shades for cards, menus, and dialogs that sit above the page.

Handing tokens to developers

Copy the light and dark values as CSS variables with names that match your design tokens.

How to build a dark palette in 4 steps

  1. Enter your light colors. Set a name and a role for each, and keep one row with the Background role.
  2. Look at the dark color generated for each row, and the contrast badges on Text and Accent rows.
  3. Edit any dark color you want to change by hand, and check the side-by-side preview.
  4. Pick how dark mode switches, then click Copy CSS and paste it into your stylesheet.

Note: The dark colors update as you change a light color or a role. A color you edit by hand stays as you set it.

How the conversion works

  • Background row: the other colors are calculated against it. If no row has the Background role, the tool assumes white for light mode and #121212 for dark mode.
  • Contrast: ratios follow the WCAG 2 formula and are measured against the Background of the same mode. Large text and UI parts need 3:1, normal text needs 4.5:1, and 7:1 is the enhanced level.
  • Names: the color name becomes the CSS variable. Spaces and symbols turn into hyphens, so Muted text becomes --muted-text.
  • Output: colors are solid hex codes. They are not opacity-based, and they do not include hover or disabled states.

How each role is converted

The rule for each role, and what you get from the example palette that loads with the tool.

RoleWhat the tool doesExample
BackgroundKeeps the hue, lowers the saturation, and sets a dark lightness#ffffff → #121212
SurfaceSets a lighter gray than the dark background, by a step based on the light-mode difference#f3f4f6 → #1d1e20
TextFlips the lightness within a light range, mutes the saturation, and raises it until the contrast is 4.5:1#111827 → #e0e2e6
Text (muted)Same rule, so the result sits lower on the scale but still reaches 4.5:1#6b7280 → #898b8f
AccentLowers the saturation, lightens the color, and raises it until the contrast is 4.5:1#4f46e5 → #7771e0
BorderSets a lighter gray than the dark background, by a larger step than a surface#e5e7eb → #2b2d30
OtherFlips the lightness and lowers the saturation slightlyDepends on the color

Elevation in dark mode. Material Design raises a surface by laying a semi-transparent white overlay on it. A 1dp surface uses about 5% white over #121212, which is close to #1e1e1e. The Surface rule here gives a similar result as a solid color.

Text emphasis. Material uses white at 87% opacity for high-emphasis text, 60% for medium, and 38% for disabled text. This tool gives solid colors instead, so you can check the exact contrast of each.

Dark theme practice: surfaces, text, and switching

Guidance from Material Design and WCAG that explains the choices this tool makes.

Show depth with lighter surfaces, not shadows

Shadows are hard to see on a dark background. Material Design's dark theme says that as a surface rises in elevation it becomes lighter, using a semi-transparent white overlay on the base surface. Add Surface rows for each level you need.

Use a dark gray base and softer text

The recommended base is #121212, not pure black. Text does not need to be pure white either. Material sets high-emphasis text at 87% white. A tone like #e0e0e0 reads comfortably and still has a high contrast ratio on #121212.

Switch themes with CSS variables

Define each color once as a CSS variable, then override the values for dark mode. The prefers-color-scheme media query follows the system setting. An attribute or a class on the html element lets you add a manual toggle. Setting color-scheme also tells the browser to style built-in controls and scrollbars to match.

Check more than the text

WCAG 2.1 asks for 3:1 contrast for user interface parts and graphics, such as the border of an input or an icon button, not only for text. A border that looks fine on light can disappear on dark, so look at the Border row too.

Dark mode color mistakes

Flipping every color

A plain inversion turns pastel surfaces into bright ones and leaves saturated accents glowing on dark backgrounds. Contrast on text can end up too low or too harsh.

💡 See the solution▼
Set a role for each color. Backgrounds and surfaces are rebuilt as grays, text is rebuilt as light tones, and accents are softened and lightened.

Pure black with pure white text

The contrast between #000000 and #ffffff is the maximum possible. Material Design notes that light text on dark gray has less contrast than on black, and says dark gray surfaces reduce eye strain.

💡 See the solution▼
Use a dark gray base such as #121212 and an off-white text color. The Text rule here caps the lightness below white.

An accent that passes on light but fails on dark

A brand blue with good contrast on white can drop below 4.5:1 on a dark background, which makes links and small text hard to read.

💡 See the solution▼
Use the Accent role. The tool lightens the color until it reaches 4.5:1 and shows the ratio in the badge. Edit the dark color if you want a different shade.

Borders and dividers that vanish

A light gray border becomes almost the same tone as a dark surface, so cards and inputs lose their edges.

💡 See the solution▼
Mark them with the Border role and read the dark ratio. For input borders, WCAG asks for 3:1 against the adjacent color, so edit the dark color if the ratio is lower.

Dark mode color FAQ

Q.Does the tool just invert my colors?

Q.

A. No. Each color is converted according to its role. Backgrounds become a dark gray, surfaces and borders become slightly lighter grays, text becomes a light tone, and accent colors are lightened and softened. Text and accent colors are then lightened further until they reach a 4.5:1 contrast ratio on the dark background. The Other role is the exception, since it only flips the lightness.

Q.Why is the dark background not pure black?

Q.

A. Material Design's dark theme guidance recommends #121212 as the surface color. It notes that light text on dark gray has less contrast than light text on black, and a gray base leaves room to show raised surfaces as lighter shades. The tool creates #121212 from a white background.

Q.What contrast ratio should I aim for?

Q.

A. WCAG 2 asks for at least 4.5:1 for normal text (AA) and 7:1 for the enhanced level (AAA). Large text and user interface parts such as borders around inputs need at least 3:1. The badges next to each Text and Accent color show the level it reaches against the background of the same mode.

Q.Can I change a generated dark color?

Q.

A. Yes. Use the color picker or type a hex code in the Dark field. The row is then marked as edited and keeps your value, while the other colors keep following the Background row. Click the reset icon on a row, or Reset edited dark colors, to return to the generated values.

Q.How do I use the CSS in my project?

Q.

A. Click Copy CSS and paste it into your stylesheet. Each color becomes a CSS variable named after the color, such as --primary. Choose how dark mode switches: the prefers-color-scheme media query, a data-theme attribute, or a .dark class on the html element. Then use var(--primary) in your styles.

Q.What does each role do?

Q.

A. Background sets the base of the page. Surface is for cards and panels that sit on it, and Border is for dividers and outlines. Text covers body and muted text, and Accent covers buttons, links, and status colors. Other uses a plain lightness flip for anything that does not fit these.

Q.Why do my surface colors differ in lightness?

Q.

A. In dark mode, a surface that sits higher is shown with a lighter shade, not a shadow. The tool sets each surface this way, and the lightness step depends on how far the light-mode surface is from the light-mode background. To get several levels, add more Surface rows with different light colors.

Q.Does it create the 87% and 60% opacity text colors from Material Design?

Q.

A. No. The tool outputs solid hex colors. Material Design's dark theme sets text emphasis with white at 87%, 60%, and 38% opacity. If you prefer opacity, apply those values in your own CSS. The solid colors here give you a ready alternative that you can check for contrast.

Q.Is my palette saved or sent anywhere?

Q.

A. No. The colors are converted in your browser with JavaScript and nothing is sent to a server. The palette is not saved either, so copy the CSS before you leave the page.

User Feedback & Request

Your feedback
makes this tool better.

Tell us which features you'd like, what should be fixed, or which new tool you'd like to see. An engineer reads every submission and uses it to guide development.

Send feedback