
When dark mode transitioned from a niche developer preference to a system-level expectation, designers and developers assumed the transition would be simple: just flip the color variables. Change the background from white to black, change the text from black to white, and call it a day.
But if you have ever looked at white text on a dark background and felt your eyes straining, or noticed that the letters seemed oddly thick and blurry, you have run into a fundamental optical illusion. Text physically looks different depending on the background it sits on.
To create truly accessible, beautiful user interfaces, we must understand the weight of the dark and optimize our typography for both spectrums.
The reason dark mode typography requires special attention comes down to physics and human biology. This phenomenon is known as the irradiation illusion (or halation).
Light objects on a dark background appear larger and more luminous than dark objects of the exact same size on a light background. On our screens, light-colored subpixels bleed into the surrounding dark pixels.
The practical consequence of this is that white text on a black background looks heavier (bolder) than black text on a white background.
If you use a font weight of 400 (Regular) in light mode, that same weight can look closer to 500 (Medium) in dark mode. This excess "glow" fills the counters (the enclosed spaces inside letters like o, e, and a), reducing legibility and causing eye fatigue over long reading sessions.
Historically, adjusting font weight for dark mode was difficult. Standard web fonts are loaded in static weights (e.g., 300, 400, 500, 700). Stepping down from a Regular 400 to a Light 300 in dark mode is often too extreme, making the text look spindly and weak.
With Variable Fonts, we have a continuous axis of weight adjustment. This allows us to subtly shave off a fraction of the font's weight in dark mode—just enough to counteract the irradiation illusion without losing the visual hierarchy.
/* Defining our typographic variables */
:root {
--font-weight-body: 400;
--font-weight-bold: 700;
--letter-spacing-body: 0em;
--bg-color: #ffffff;
--text-color: #1a1a1a;
}
/* Optimizing typography for dark mode */
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #121212;
--text-color: #e4e4e7; /* Avoid pure white #fff */
/* Shave off weight to combat the irradiation illusion */
--font-weight-body: 370;
--font-weight-bold: 660;
/* Add a tiny bit of tracking (letter-spacing) */
--letter-spacing-body: 0.015em;
}
}
body {
background-color: var(--bg-color);
color: var(--text-color);
font-weight: var(--font-weight-body);
letter-spacing: var(--letter-spacing-body);
transition: background-color 0.3s, color 0.3s;
}
By reducing the weight from 400 to 370 in dark mode, the characters occupy the exact same perceived optical weight as they do in light mode.
Font weight is only half the battle. Because light text on a dark background bleeds outward, the negative space between characters shrinks.
To maintain optimal legibility:
0.01em to 0.02em keeps letters from bleeding into one another.line-height slightly (e.g., from 1.5 to 1.55) provides essential breathing room between lines of text.Pure white text (#FFFFFF) on a pure black background (#000000) creates too much contrast. The extreme luminance ratio causes visual vibration, making it painful to read.
Instead, aim for a dark gray or deep slate background combined with an off-white, light gray, or warm cream text color. A background like #121212 or #1E293B combined with text colored #F1F5F9 or #E2E8F0 will easily pass WCAG AA and AAA accessibility contrast guidelines while remaining comfortable for the eyes.
Designing for dark mode is more than a simple color-inversion script. By understanding how light behaves on digital screens, we can use CSS variables, variable fonts, and careful spacing adjustments to build responsive interfaces that look incredibly polished, crisp, and comfortable in any light.
Photo by Matheus Bertelli on Pexels