Design

Dark Mode Basics: Switch Colors with prefers-color-scheme and CSS Variables

Dark mode is now a standard expectation on many sites and apps, valued for readability in dark settings, power savings, and respecting user preference. This article explains why dark mode matters, how to use the prefers-color-scheme media query, how to switch colors with CSS variables, how to avoid pure black while keeping enough contrast, how to adjust images and shadows, and how to roll out an implementation step by step.

Published: 2026-10-16

Have you seen a "dark mode" or "dark theme" option in your phone or PC settings? It is the display mode that darkens the background and lightens the text. In recent years, dark mode has spread widely at the OS level, and there is growing expectation that websites and apps should "automatically go dark to match the device setting." This article explains why dark mode support matters, how it works, and the points where implementations commonly stumble.

Why Dark Mode Support Matters

Dark mode is a color scheme that shows a dark background with light text and UI. Against the traditional light background (light mode), many users now prefer dark mode. The reasons support is expected can be grouped into three.

  • Less eye strain: At night or in a dark room, a bright screen feels glaring. Darkening the background softens the contrast with the surroundings and reduces eye strain.
  • Power savings: On OLED displays, black pixels emit little light, so a dark scheme can reduce battery consumption in some cases.
  • Preference and consistency: For someone who keeps their OS in dark mode, having only your site suddenly glow bright feels jarring. Matching the device setting keeps the experience consistent.

In short, dark mode support is not just a trend; it carries practical value in readability, power savings, and respecting preference. When you design both light and dark palettes, having a tool that converts color values back and forth makes moving between HEX and RGB smooth, such as the Color Code Converter.

Detecting Preference with prefers-color-scheme

The starting point for dark mode support is knowing which mode the user has chosen on their device. For this you use the CSS media query prefers-color-scheme. If the OS or browser setting is dark mode the value is dark, and if it is light mode the value is light.

@media (prefers-color-scheme: dark) { /* put the dark color scheme here */ }

Inside this media query, you write the styles you want to apply only in dark mode. A clear structure is to prepare your base styles for light mode and gather the dark-mode overrides inside prefers-color-scheme: dark.

The key point is that it switches automatically without any explicit action from the user. Even without placing a button on your site, simply reflecting the device setting gives you a baseline of support. If you also want a "site-specific toggle button," a common approach is to combine it with the CSS variables described next and swap a class or attribute with JavaScript.

Switching Colors with CSS Variables

If you specify dark mode element by element, the code balloons and maintenance quickly becomes hard. This is where CSS custom properties (CSS variables) shine. Instead of writing colors directly, you define them once as variables and have elements reference those variables.

:root { --bg: #ffffff; --text: #1a1a1a; }
@media (prefers-color-scheme: dark) { :root { --bg: #121212; --text: #e6e6e6; } }

Like this, you define the light-mode colors in :root and assign different values to the same variable names in dark mode. Then, if each element is written as background: var(--bg); or color: var(--text);, the whole palette changes at once just by switching modes. The biggest benefit is being able to centralize your color definitions.

For the colors you store as variables, it helps to name them by role, such as background, text, link, border, and accent. When deciding which color maps to which HEX value as a light/dark pair, fine-tuning while moving between HEX, RGB, and HSL with the Color Code Converter makes it easier to balance lightness and saturation.

Avoiding Pure Black and Ensuring Contrast

A common dark mode mistake is making the background pure black (#000000) and the text pure white (#ffffff). It looks crisp at first, but pure white on pure black has contrast that is too strong; text can appear to bleed (halation), and reading for long periods tires the eyes.

What is recommended instead is a dark gray rather than pure black for the background (for example around #121212) and a slightly toned-down white rather than pure white for the text (for example around #e6e6e6). Softening the difference between light and dark makes things much easier to read.

On the other hand, if you soften it too much and contrast falls short, the text becomes hard to read. The accessibility guidelines (WCAG) recommend a contrast ratio of at least 4.5:1 for body text. Because dark mode is a separate palette from light mode, it is essential to check the contrast in both modes individually. To see whether a palette meets the criteria, enter the background and text colors into the Color Contrast Checker and you can instantly confirm the ratio and pass/fail.

  • Avoid pure black for the background; base it on a dark gray.
  • Avoid pure white for text; use a white with slightly reduced lightness.
  • Use the Color Contrast Checker in both light and dark modes, aiming for at least 4.5:1.

Adjusting Images and Shadows

Even if you switch colors with variables, some elements will not fall into place on their own. The prime examples are images and shadows.

Images and logos: A black logo on a transparent background disappears against a dark background. You need to provide a logo with inverted colors for dark mode, or give the logo some padding. For photos, slightly lowering the brightness in dark mode helps them blend with the surroundings and keeps them from looking like they float on screen.

Shadows: In light mode, adding a faint shadow to make an element appear raised is a common technique. But on a dark background, a black shadow is barely visible and produces no sense of depth. In dark mode, it is sometimes more effective to weaken shadows, or instead express element boundaries with a light outline or a difference in lightness from the background.

In this way, dark mode support is not "invert the colors and done"; it includes the work of redesigning how elements appear. That said, trying to perfect everything never ends, so a good order is to handle text-versus-background contrast first, then images and shadows.

How to Roll Out an Implementation

Finally, here is a sequence for rolling out dark mode support without strain. Rather than aiming for perfection at once, building up in stages is realistic.

  • 1. Turn colors into variables: First, replace your existing light-mode palette with CSS variables by role, such as background, text, and border. This alone greatly improves maintainability.
  • 2. Define dark values: Inside prefers-color-scheme: dark, assign dark values to each variable. The trick is to choose values that avoid pure black and pure white.
  • 3. Verify contrast: For both light and dark palettes, check the ratios of body text and headings with the Color Contrast Checker and fine-tune to meet the criteria. The Color Code Converter helps when adjusting color values.
  • 4. Review images and shadows: Adjust logos that become hard to see and shadows that stop working on a dark background.
  • 5. Check on real devices: On both PC and smartphone, switch the OS setting and check how it actually looks.

Once you grasp the basics of CSS variables and prefers-color-scheme, dark mode support is by no means difficult. What matters is managing colors in one place and proceeding while checking contrast in both light and dark modes. Start by organizing your palette with the Color Code Converter and confirming readability with the Color Contrast Checker.

Please note that this article is intended to provide general information. The specifications of media queries and accessibility guidelines can be updated. When implementing, make your decision after checking the latest official documentation and browser support status.

FAQ

Why is dark mode support necessary?

It offers three practical benefits: less eye strain in dark settings, power savings on OLED displays, and respect for users who keep their OS in dark mode. Switching the palette to match the device setting keeps the experience consistent and avoids the jarring feeling of only your site suddenly glowing bright.

What is prefers-color-scheme?

It is a CSS media query that detects whether the user has chosen light or dark mode on their device. By writing the styles you want only in dark mode inside "@media (prefers-color-scheme: dark)," the palette switches automatically to match the OS or browser setting, without any explicit action from the user.

Should the dark mode background be pure black?

Pure white (#ffffff) on pure black (#000000) has contrast that is too strong, causing halation and tiring the eyes. It is better to use a dark gray (around #121212) for the background and a slightly toned-down white (around #e6e6e6) for text to soften the difference. Just be sure not to soften it so much that contrast falls short; aim for at least 4.5:1.

Why do CSS variables make things easier?

Writing colors directly into each element means rewriting everywhere for dark mode, which is hard to maintain. With CSS variables, you can centralize color definitions in one place such as :root, and in dark mode you simply assign different values to the same variable names to switch the whole palette at once.

Are the colors I enter into the WAZA TOOLS color tools sent to a server?

WAZA TOOLS' Color Code Converter and Color Contrast Checker run entirely in your browser, so the color values you enter are never sent to or stored on a server. They work on smartphones too, and you can use them as many times as you like, for free.