Dark Mode Done Right: Automatic Theme Switching

When I started building Jottings, I knew one thing for sure: readers have strong opinions about how they want to read content. Some love the brightness of a white page. Others can't stand it after sunset. And then there's everyone in between, who just wants their device to decide.

The thing about dark mode that most sites get wrong is that they treat it like a feature. A checkbox. A toggle that the user has to actively choose. But dark mode isn't a feature—it's an accessibility need, a battery concern, and a personal preference all rolled into one.

Why Dark Mode Matters

Let me break down why dark mode isn't just a nice-to-have:

Eye Strain and Comfort: In low-light environments—your bedroom at 11 PM, a coffee shop with dim lighting, anywhere outside in bright sun (yes, really—dark text on white is harder to read in sunlight)—a white background feels like staring directly at a light bulb. Studies show that dark interfaces reduce eye strain in low-light conditions.

Battery Life: If you're reading on an OLED screen (phone, tablet, high-end laptop), dark pixels literally use less power than bright ones. That's not a design preference—that's physics. A website with a black background can meaningfully extend your device's battery life.

Personal Preference: Some people just prefer dark mode. Always. And they shouldn't have to tell every website they visit. They've already set their OS preference. Websites should respect that.

Inclusivity: Not everyone reads on the same device, at the same time of day, in the same lighting. Dark mode is part of making content accessible to more people.

The Three-Mode Approach

At Jottings, we implemented three distinct modes:

Light Mode - The default for daylight reading. Crisp black text on a clean white background, with carefully chosen grays for secondary information. It's the traditional design many of us grew up with.

Dark Mode - True dark theme. Black background with white text and adjusted grays that maintain contrast and readability without burning your eyes. The colors are specifically tuned to work well at night.

Auto Mode - This is the key innovation. Instead of forcing users to choose, Auto mode respects your operating system preference. Windows 11 in dark mode? Your browser automatically switches. macOS in light mode? Stays light. Phone switches to dark after sunset? The website follows along.

The auto mode is what makes dark mode actually useful as a feature—because it stops being a feature you have to think about.

How CSS Variables Make It All Work

The technical magic behind theme switching is simple but powerful: CSS variables.

Instead of hardcoding colors throughout our stylesheet, we define everything as variables at the root level:

:root {
  /* Light Theme (default) */
  --color-bg: #ffffff;
  --color-text-primary: #000000;
  --color-text-secondary: #666666;
  --color-border: #e1e1e1;
  --color-hover: #f8f8f8;

  /* Typography, spacing, shadows, etc. */
  --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --space-md: 1rem;
}

Then we override these variables when dark mode is enabled:

[data-theme="dark"] {
  --color-bg: #000000;
  --color-text-primary: #ffffff;
  --color-text-secondary: #b3b3b3;
  --color-border: #333333;
  --color-hover: #111111;
}

Now every element—from the page background to buttons to borders—uses these variables instead of hardcoded colors:

body {
  background-color: var(--color-bg);
  color: var(--color-text-primary);
  transition: background-color 200ms ease, color 200ms ease;
}

a {
  color: var(--color-link);
}

button:hover {
  background-color: var(--color-hover);
}

When the theme changes, everything updates automatically. No need to reload. No flickering. The transition property makes it smooth and natural.

Auto Mode: Using System Preferences

The real power is in auto mode. Instead of asking users to pick a theme, we detect their system preference with a single CSS media query:

@media (prefers-color-scheme: dark) {
  :root {
    /* Dark mode colors */
    --color-bg: #000000;
    /* ... */
  }
}

The prefers-color-scheme media query does something remarkable—it reads the user's operating system preference. When they switch their phone to dark mode at sunset (which many do automatically), the website knows. When they use Windows in dark mode, the website knows.

Here's what happens:

  1. User sets their OS to dark mode (or it happens automatically at sunset)
  2. prefers-color-scheme: dark evaluates to true
  3. CSS variables switch to dark mode colors
  4. The page theme changes instantly
  5. No user action required

On the JavaScript side, you can detect and respect this preference:

const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (prefersDark) {
  document.documentElement.setAttribute('data-theme', 'dark');
}

Then listen for changes so if the user switches their system preference while your page is open, the site updates in real-time.

Color Contrast: The Part Everyone Forgets

Here's where most dark mode implementations fail: they just invert the colors and call it a day.

Bad dark mode:

  • White text on black background (WCAG AAA contrast ratio: 21:1) ✓ technically good
  • But... pure black (#000000) is actually harsh
  • Pure white (#ffffff) is actually harsh too

Good dark mode (what we did):

  • Off-white text (#ffffff) on near-black background (#000000) - feels softer
  • Secondary text in #b3b3b3, not pure white - creates hierarchy
  • Borders in #333333 instead of super light - divides space without glaring
  • Hover states in #111111 - just slightly lighter than pure black

The goal is readability without eye strain. Full contrast makes it technically accessible but practically harder to read for extended periods.

Transitions Without Flickering

One detail matters enormously: smoothness.

When dark mode activates, we use a 200ms CSS transition:

body {
  transition: background-color 200ms ease, color 200ms ease;
}

This 200ms fade is fast enough to feel responsive, slow enough to not be jarring. It's that sweet spot where the change feels intentional rather than glitchy.

Without it, the page flashes white-to-black or black-to-white, creating the "flash of unstyled content" problem. Users hate it. It feels broken.

The Philosophy: No Forced Preferences

Here's my take on dark mode that I don't think gets said enough: stop making me choose.

Dark mode isn't a feature that needs to be "enabled." It's not a preference to be configured. It's a basic expectation. If I've set my phone to dark mode, my browser to dark mode, and my OS to dark mode, the websites I visit should have the decency to respect that.

But some sites make you click a toggle on every visit. Others ignore your preference entirely. A few try to guess your preference at 2 AM (good luck with that).

At Jottings, the philosophy is simple: we respect the system preference, period. No toggle required. No confusion. No settings buried three levels deep.

If you want to override it (because maybe you're an odd one out), that's something we'd add. But the default is: your device decides. And if your device decides to switch at sunset, our sites follow along.

When You Build Dark Mode Right

There's something beautiful about opening a website at night and not immediately getting blinded. It's such a small thing—respecting a preference your device already knows about—but it's the kind of attention to detail that separates "apps I use" from "apps I actually enjoy."

Dark mode done right is invisible. You don't think about it. You just notice you're not squinting.

And honestly? That's the goal.


Want to build a site that respects how people actually read? Jottings handles theme switching automatically with zero configuration on your end. Choose light, dark, or let your device decide—and your readers get a seamless experience across all conditions.

Create your Jottings site today and let your content shine without the glare.