How to Add Dark Mode to WordPress
Without FOUC (Flashing Issues)
That blinding white flash when your dark mode loads? It has a name — FOUC — and it’s silently killing your user experience. Here’s what it is, why it happens, and how to actually fix it for good.
Updated 2026
Technical & UX Guide

There is something deeply frustrating about dark mode done wrong. You enable it on your WordPress site, a visitor with dark mode preferences lands on your page, and for a fraction of a second — sometimes longer — the entire screen flashes white before the dark theme kicks in. It is jarring. It is disorienting. And if the visitor is in a dark room at night, it is physically uncomfortable. That is not a minor aesthetic hiccup. That is a UX failure that happens on every single page load.
This problem has a specific name in web development: FOUC — Flash of Unstyled Content. And when it comes to WordPress dark mode, it is one of the most common complaints you will find in plugin reviews, developer forums, and support threads. People install what looks like a perfectly good dark mode plugin, only to discover that every page transition brings that painful white flash back.
This guide explains exactly why FOUC happens with WordPress dark mode, what separates plugins that solve it from those that simply ignore it, and how to implement a flash-free dark mode that works correctly from the first millisecond of every page load. If you have already been burned by this problem, this is the article you were looking for when you searched for it.
We will be discussing this largely in the context of Nexu Eclipse — the WordPress dark mode plugin built specifically to eliminate FOUC at its root — but the technical principles apply regardless of what approach you take.
What is FOUC and why does WordPress dark mode cause it?
FOUC — Flash of Unstyled Content — originally referred to a browser behavior where page content would briefly appear without its CSS styles applied, because the HTML loaded faster than the stylesheet. Browsers largely solved this decades ago. But the term has been borrowed to describe a closely related problem in dark mode: the momentary display of the light-mode version of a page before the dark styles are applied. The underlying cause is well-documented in Mozilla’s documentation on prefers-color-scheme, which outlines the correct CSS-first approach to OS-level dark mode detection.
For dark mode, the specific sequence that causes the flash is this: the browser loads and renders your page in its default state (white background, dark text), then your JavaScript runs, reads the user’s saved preference for dark mode, and applies the dark class or CSS variables. By the time JavaScript executes, the browser has already painted the screen. The user sees the white version first, then it snaps to dark. That snap is the flash.
A 2023 study by the Nielsen Norman Group found that unexpected visual disruptions during page load significantly increase user frustration and reduce perceived page quality — even when the rest of the experience is excellent. For users visiting your site in low-light environments, which is when dark mode matters most, the flash is not just annoying. It physically disrupts their visual adaptation to the dark environment. Eyes adjusted to low light are genuinely hurt by sudden bright-screen flashes. Nielsen Norman Group’s research on dark mode usability documents the readability and fatigue differences between implementations in detail.
WordPress makes this problem particularly acute because of how the platform renders pages. By default, WordPress is a server-rendered CMS: the server generates HTML and sends it to the browser, which renders it immediately. There is no React hydration step, no client-side routing that could intercept the render. The page appears, and then scripts run. This architecture makes the JavaScript-dependent dark mode approach structurally incompatible with a flash-free experience.
This is not a problem specific to one plugin or one theme. It is the unavoidable result of applying dark mode via JavaScript after page render, which is what the majority of WordPress dark mode plugins do.
Why most free WordPress dark mode plugins always flash
The free plugin ecosystem for WordPress dark mode is large. There are dozens of options available in the official repository, and most of them share the same fundamental architecture: they add a JavaScript file that runs on page load, checks localStorage or a cookie for the user’s dark mode preference, and adds a class to the body element. Clean logic. Simple implementation. Guaranteed flash.
Most WordPress performance optimization guides recommend deferring non-critical JavaScript. This is good general advice that reduces render-blocking resources. But applying it to dark mode initialization scripts makes the FOUC dramatically worse. A deferred script runs after the document is interactive, which means the page has already fully rendered in light mode before the dark preference is applied. Plugins that defer their theme-switching script are guaranteeing a flash on every page load for dark mode users.
Some plugins argue their preference storage method avoids flashing. Cookies can theoretically be read server-side, which could enable server-side class injection. But in practice, most plugins using cookies still apply the class via JavaScript on the client. localStorage is inherently client-side only and cannot be read during server render. Neither approach resolves the fundamental timing issue unless the plugin is specifically architected to use the server-side cookie read for dark mode class injection into the HTML response.
The cheapest way to implement dark mode in CSS is to use filter: invert(1) on the entire page. This inverts everything including images and videos, producing a photographic negative effect on your content. Many free plugins use this approach because it requires no design work. The result is dark mode that looks broken: inverted product photos, strange-looking profile pictures, and videos with their colors reversed. Quality dark mode implementations individually address backgrounds, text, and interface elements without touching images at all.

The correct technical approach to flash-free WordPress dark mode
Solving FOUC properly in WordPress requires addressing the problem at the right layer of the rendering pipeline. The flash happens because the browser paints the page before dark mode styles are applied. Therefore, the dark mode class or attribute must be present in the HTML before the browser makes its first paint decision.
There are two architecturally sound approaches. The first is server-side rendering of the dark mode class: the server reads a cookie that stores the user’s preference and injects the dark mode class directly into the HTML tag before sending the response. When the browser receives the HTML, the dark class is already present, and the CSS that depends on it applies from the first paint. No JavaScript needs to run before the page looks correct. This is the gold standard for WordPress dark mode.
The second approach, which works as a fallback, is to place a tiny, synchronous, render-blocking inline script in the <head> that reads the preference and applies the class before the browser processes any of the page body. This script must be synchronous (not async, not deferred) and must execute before the browser’s paint cycle begins. Done correctly, the flash window is reduced to near zero, although it is technically still possible on very slow connections.
CSS has a native media query,
prefers-color-scheme: dark, that reads the user’s operating system preference without any JavaScript. A well-engineered dark mode plugin uses this as the default behavior — matching the OS setting automatically — and then layers JavaScript-based toggle behavior on top for users who want to override it. Users who have dark mode set at the OS level get it from the very first byte of page render, with zero flash possible because it is handled entirely in CSS. Only users who have divergent preferences (OS in light mode, site preference in dark, or vice versa) need the JavaScript layer, and for them the flash window is minimized by the techniques described above.
What “smart” dark mode actually means: beyond background color
Every time someone calls a dark mode implementation “smart,” it is worth asking what that actually means. A truly intelligent dark mode does much more than swap a white background for a dark grey one. The visual problems that arise from a naive dark mode implementation go far beyond FOUC, and a complete solution has to address all of them.
Your heading color and your paragraph text color should not automatically become identical shades of grey just because someone is in dark mode. A well-designed dark mode maintains visual hierarchy while shifting to dark. This requires the ability to set distinct dark-mode values for different element types: backgrounds, surface elements, primary text, secondary text, links, borders, and accent colors. The control panel should feel like a design tool, not a simple on/off switch.
Some elements should never be touched by dark mode. Brand logos that rely on specific color values look wrong when darkened. Infographics and charts designed with specific color coding lose their meaning when their palette is altered. Custom hero sections with carefully crafted gradient backgrounds should not be overridden. A proper exclusion system lets you specify by CSS selector, by element type, or by class name which elements are immune to dark mode transformations. This is not an edge case feature — it is essential for any site with meaningful visual design.


The switch toggle: why design matters as much as function
The dark mode toggle itself — the button or switch that lets users flip between modes — is a piece of UI that every visitor to your site will see. It should not be an afterthought. The placement, the styling, and the animation of the toggle all contribute to whether dark mode feels like a polished feature or a bolt-on addition.
Positioning flexibility is essential. The toggle should be placeable in the header, the footer, as a floating element, or injected into existing navigation menus depending on your theme’s layout. A fixed position in the bottom corner works for some sites and looks misplaced on others. Icon-only switches save space; text-labeled switches provide clarity for accessibility. Both options should be available, and the active state should be unmistakably clear.

Light vs. dark: what the actual difference looks like
The proof of any dark mode implementation is in the visual comparison. Anyone can claim their plugin produces a clean result. The side-by-side tells the real story. Below you can see the same WordPress site rendered in its default light state and with Nexu Eclipse’s dark mode active. The critical thing to notice is not just the dark background — it is that the content remains fully readable, the images are untouched, and the visual hierarchy of headings, body text, and interactive elements is preserved intact.
Advanced settings: the features that separate a real solution from a basic toggle
Once you have the core dark mode experience working correctly — flash-free, visually coherent, properly handling images — there is a layer of advanced configuration that separates a professional implementation from a basic one. These features matter less to casual users but are decisive for agencies building sites for clients, and for site owners with complex page structures.
Some pages on your site may have heavily customized visual designs where dark mode either breaks the intended effect or simply is not appropriate. A landing page with a dark hero section does not benefit from additional dark mode processing — it may already be effectively “dark mode ready” in its light version. The ability to exclude specific pages or URL patterns from dark mode processing entirely gives you the flexibility to mix dark-mode-enabled and dark-mode-excluded pages on a single site.
The most valuable dark mode experience for users is one that happens automatically at the right time. Beyond OS-level sync, some plugins support sunset/sunrise-based automatic switching, which shifts the site to dark mode when the sun sets in the user’s local timezone and back to light when it rises. This behavior mirrors what operating systems do at the system level, making the experience feel completely native and frictionless. Users who do not actively think about dark mode settings still get optimal visual comfort throughout the day.
When a user clicks the toggle, the mode switch should feel smooth rather than jarring. A CSS transition on the color properties creates a pleasant fade that signals to the user that the switch is deliberate and complete. The transition speed should be configurable — fast enough to feel responsive, smooth enough to avoid the same jarring snap that FOUC causes. This detail is small but contributes meaningfully to whether dark mode feels like a premium feature or an afterthought.

A practical checklist: what flash-free WordPress dark mode requires
If you are evaluating dark mode plugins, implementing one from scratch, or troubleshooting an existing implementation that still flashes, use this checklist to assess whether the approach is sound.
The real cost of getting dark mode wrong
A dark mode that flashes is arguably worse than no dark mode at all. Here is why: users who have dark mode preferences set at the OS level have a clear visual expectation when they land on a site. When the site’s dark mode triggers correctly and seamlessly, it confirms that the site respects their preferences. When it flashes white before switching, it creates a moment of failure, a visible reminder that the dark mode is a patch applied after the fact rather than a genuine part of the design.
That perception matters. User experience research consistently shows that trustworthiness correlates with visual polish and technical reliability. A site whose dark mode works perfectly conveys attention to detail. A site whose dark mode flashes on every navigation click conveys the opposite. For commercial sites, this directly impacts conversion rates and session length, particularly among the power-user and developer segments who are most likely to have strong dark mode preferences.
The solution is not complex. It requires choosing a plugin that has addressed the technical root cause — the render timing problem — rather than one that applies a dark class via JavaScript without regard for when in the page lifecycle that script runs. Nexu Eclipse’s FOUC-eliminated WordPress dark mode implementation addresses exactly this problem by design, not as an afterthought. When you enable it, dark mode works correctly from the first millisecond. That is the standard your visitors expect, and it is the standard your site should meet.
The WordPress dark mode that works the way it should from the first pixel
Nexu Eclipse eliminates FOUC at the architectural level. OS sync, granular color control, element exclusions, toggle design options, and flash-free rendering from first load. This is what dark mode is supposed to feel like.



Finally fixed that annoying white flash before dark mode kicks in. I tried three other plugins first, and every single one did the same thing page loads bright white, then suddenly snaps to dark like someone flicked a light switch in your face at 2 AM. this guide actually explains why it happens instead of just ignoring the problem. followed the steps, got it set up right, and now it just works. No more squinting every time I open my own site. Took me way longer to find this solution than to actually implement it
I grabbed this guide after wrestling with FOUC problems on a client's website. The part explaining why JavaScript dark mode always causes that annoying flash totally clicked, but I'm still confused if browsers figured this out ages ago, why does WordPress still have such a hard time with it?
Finally a guide that doesn't just slap a dark mode toggle on and call it done. the FOUC issue has been driving me nuts for months every plugin I tried still had that white flash