Guides / Prompting and shipping

How to Add Dark Mode to Your Website or App (Without the Flash)

How to add dark mode: follow the system setting or add a toggle, use colour tokens, avoid the white flash on load, and check contrast. Prompts included.

Mythex Team · 2026-09-29 · 5 min read

To add dark mode, define your colours as named tokens (background, text, surface, border, accent) instead of hard-coded values, give each token a light and a dark value, and switch between them with the CSS prefers-color-scheme media feature so the site follows the visitor's system setting. If you want a manual toggle too, store the choice in the browser and apply it with a tiny inline script in the page head so there's no white flash on load. Then check contrast, images and charts in both themes. In an AI app builder, one clear prompt can do most of this; the checking is where the quality comes from.

Two approaches

ApproachHow it worksGood forTrade-offs
Follow the systemCSS media feature prefers-color-scheme picks light or darkSimple sites, zero UIVisitors can't choose differently from their device
Toggle + system defaultStarts from the system setting; a Light / Dark / System switch overrides it and is rememberedApps people use a lotA little JavaScript, and the flash-on-load problem to solve

Most apps do best with the second: respect the system by default, let people override it.

Start with colour tokens

Dark mode is painful when colours are scattered through the code as white, #333 and gray-100. It's easy when every colour comes from a small set of named tokens:

TokenLightDark
backgroundnear-whitevery dark grey
surface (cards, menus)whiteslightly lighter dark grey
textnear-blackoff-white
text-mutedmid greylighter mid grey
borderlight greydark grey with a little contrast
accentyour brand colouroften a lighter or less saturated version

Each component uses the token names. Switching themes then means swapping one set of values, not editing every component.

Tips for the dark palette:

  • Avoid pure black and pure white for large areas; very dark grey and off-white are easier to read.
  • Show depth with lighter surfaces, not shadows — shadows barely show on dark backgrounds.
  • Desaturate bright brand colours slightly; they can glow uncomfortably on dark backgrounds.
  • Keep contrast readable. WCAG's AA level asks for at least 4.5:1 contrast for normal text. Muted grey text often fails this in dark themes.

With Tailwind CSS

Tailwind is the default styling tool in many AI-built apps. According to Tailwind's dark mode docs, the dark: variant uses prefers-color-scheme by default, so classes like bg-white dark:bg-gray-900 follow the system setting with no extra work.

For a manual toggle in Tailwind v4, the docs show switching the variant to a class on a parent element:

@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));

Then the app adds or removes the dark class on the root element. The docs also suggest an inline script in the head that applies the saved choice (or the system setting) before the page paints — which is exactly how you avoid the flash.

Avoiding the white flash

The flash happens because the page paints in light mode, then JavaScript loads, reads the saved choice, and switches to dark. The fix:

  1. Put a tiny inline script in the page head that reads the saved theme and sets the class on the root element before anything renders.
  2. Set the color-scheme CSS property for each theme so browser-drawn parts (scrollbars, form controls) match.
  3. Give the page an explicit background colour in both themes.
  4. If the app is server-rendered, make sure the server and the browser agree on the initial theme, or the page may re-render and flicker.

Example prompts

A full setup:

Add dark mode. First replace hard-coded colours with theme tokens (background, surface, text, muted text, border, accent) with light and dark values. Default to the visitor's system setting. Add a theme switch in the header with Light, Dark and System options, remember the choice in localStorage, and apply it with an inline script in the head so there's no white flash on load. Set color-scheme for each theme. Keep the current light design exactly as it is.

Fixing what's left:

Check every page in dark mode and fix: text with low contrast (aim for at least 4.5:1), hard-coded white backgrounds, borders that disappear, charts with dark text on dark backgrounds, and logos that vanish. Don't change the light theme.

Images and charts:

Use a light version of the logo in dark mode. Make chart axes, gridlines and labels use theme tokens. Give screenshots a subtle border in dark mode so they don't blend into the background.

Step by step

  1. Audit colours. Find hard-coded colours and replace them with tokens. This is most of the work.
  2. Define dark values for each token.
  3. Follow the system with prefers-color-scheme (or Tailwind's default dark:).
  4. Add a toggle if you want one: Light, Dark, System. Store the choice in the browser; for logged-in apps you can also save it to the user's profile.
  5. Prevent the flash with the inline head script and color-scheme.
  6. Check the tricky parts: logos, icons, images with white backgrounds, charts, code blocks, maps, embeds, emails.
  7. Test both themes on desktop and phone, with the system set to light and to dark, and after a hard refresh.

Common mistakes

  • Inverting everything. A filter that inverts colours ruins photos and brand colours.
  • Hard-coded colours left behind. One white card in a dark page stands out immediately.
  • Low-contrast grey text. Looks stylish, fails readability.
  • White flash on load. Especially noticeable on phones at night.
  • Forgetting third-party embeds. Maps, videos and widgets may stay light; check whether they have a dark option.
  • Toggle with only two states. Once someone clicks it, they can't go back to following the system.
  • Breaking the light theme. Say explicitly in your prompt that the light design should stay the same.

Checklist

  • All colours come from theme tokens
  • Follows the system setting by default
  • Optional toggle with Light, Dark and System, remembered
  • No white flash on load or refresh
  • color-scheme set so form controls and scrollbars match
  • Text contrast at least 4.5:1 in both themes
  • Logos, images, charts and embeds checked in dark mode
  • Light theme unchanged
  • Tested on desktop and phone

Dark mode with Mythex

Apps built on Mythex use Vite, React, TypeScript and Tailwind by default, so the Tailwind approach above applies directly: paste the full-setup prompt into chat, then check Preview in both themes and at phone size. Mythex's design prompting advice is to name what to change and what to keep, which matters here — say the light theme must stay as it is. See Design & UI prompts, and roll back with a checkpoint if a pass goes wrong.

For more on getting the look right, see how to design a good-looking app with AI and how to write prompts for AI app builders.

Questions

How do I make my website follow the device's dark mode setting?

Use the CSS prefers-color-scheme media feature, which tells you whether the visitor's system is set to light or dark. Tailwind's dark: variant uses it by default.

Why does my site flash white before switching to dark mode?

The saved theme is applied by JavaScript after the page has already painted. Fix it with a tiny inline script in the page head that sets the theme class before anything renders, and set an explicit background colour for both themes.

Should dark mode be pure black?

Usually not. Very dark greys are easier on the eyes for long reading and let you show depth with slightly lighter surfaces. Pure black can suit OLED-focused or media-heavy designs.

Do I need a dark mode toggle if I follow the system setting?

Not strictly. Following the system is a good default, but a toggle with Light, Dark and System options helps people who want your site to differ from their device setting.

Keep reading

  • How to Publish an App on Google Play: The Real Play Console Steps — How to publish an app on Google Play: developer account, Create app, store listing, App content forms, the 12-tester closed test and production release.
  • How to Publish an App on the App Store: TestFlight to Approval — How to publish an app on the App Store: Developer Program, App Store Connect, TestFlight, listing, App Privacy, submitting for review and rejections.
  • How to Use Google AI Studio: Playground, Build Mode and Vibe Coding With Gemini — How to use Google AI Studio: test Gemini in the Playground, get an API key, vibe code an app in Build mode, and know when to move to a full-stack builder.
  • Is Vibe Coding Safe? The Real Risks and What to Check Before You Publish — Is vibe coding safe? It can be. The real risks (data leaks, exposed keys, abuse), how to keep secrets safe, and a 30-minute check before you publish.
  • Vibe Coding for Beginners: How to Start, Step by Step — A vibe coding tutorial for complete beginners: pick a tool, write a first prompt, test, fix and publish a small app in one afternoon. No coding needed.
  • 30 Vibe Coding Prompts You Can Copy (Cheat Sheet) — 30 vibe coding prompts you can copy and paste, grouped by stage: first build, planning, design, data, fixing bugs, testing, security and publishing.

Start building free · Templates · Docs

አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)