Over 80% of email users have dark mode enabled on at least one device. And every major email client handles it differently — some invert your colors, some don't, and some do something in between that nobody asked for.
The result: your carefully designed email shows up with white text on a white background, invisible logos, or buttons that look like they were designed in 2004. This guide covers what actually works for dark mode email in 2026, with specific React Email examples you can ship.
The problem: every client does it differently
There is no single “dark mode” behavior for email. Clients fall into three categories based on how aggressively they rewrite your styles:
No change
Apple Mail, iOS Mail
Respects your CSS; applies @media query if present
Partial
Gmail (Android/iOS)
Inverts light backgrounds to dark; may swap text colors
Full rewrite
Outlook (Windows)
Ignores your dark mode CSS entirely; applies its own palette
Apple Mail and iOS Mail are the good citizens — they support @media (prefers-color-scheme: dark) and let you control everything. Gmail does a partial inversion that you can influence but not fully control. Outlook on Windows rewrites colors using its own algorithm and ignores your media queries completely.
The 3 dark mode strategies
1. No action (let the client handle it)
Do nothing. Let each email client apply its own dark mode logic. This is what most teams ship by default — and honestly, for simple transactional emails with minimal branding, it's often fine.
When to use it: plain-text-heavy emails, password resets, verification codes. Anything where the content matters more than the design.
2. Partial (meta tag + safe defaults)
Add the color-scheme meta tag to signal that your email supports both light and dark rendering. Then use colors that degrade gracefully when inverted.
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">The first meta tag is the standard. The second is a legacy Apple Mail variant — include both for maximum coverage. This tells clients “I've thought about dark mode” and prevents some of the more aggressive auto-inversions.
3. Full (media query + dark palette)
Define explicit dark mode styles using a CSS media query. This gives you full control in clients that support it (Apple Mail, iOS Mail, some Outlook versions on macOS).
@media (prefers-color-scheme: dark) {
.email-body {
background-color: #1a1a2e !important;
color: #e0e0e0 !important;
}
.email-heading {
color: #ffffff !important;
}
.email-button {
background-color: #f59e0b !important;
color: #1a1a2e !important;
}
.email-muted {
color: #a0a0b0 !important;
}
}!important declarations are necessary in email CSS. Email clients strip specificity and inject their own styles, so without !important your dark mode overrides will often be ignored.Safe color choices
The biggest dark mode failures come from using pure white (#ffffff) and pure black (#000000). When a client inverts these, you get harsh contrast or invisible elements.
- Off-white backgrounds: #f5f5f5, #fafafa
- Near-black text: #1a1a1a, #2d2d2d
- Dark mode background: #1a1a2e, #1e1e2e
- Dark mode text: #e0e0e0, #d4d4d8
- Muted accents that work on both light and dark
- Pure white #ffffff for backgrounds
- Pure black #000000 for text
- Light gray text on white (disappears when inverted)
- Thin colored borders (become invisible on dark)
- Colors that rely on background contrast to be readable
Use off-white and near-black instead of pure white and pure black. When clients auto-invert, the shift is subtle instead of catastrophic. A #f5f5f5 background inverted is a dark gray — still readable. A #ffffff background inverted is pure black — harsh and jarring.
Image handling
Images are the second most common dark mode casualty. Logos on transparent backgrounds become invisible. Product screenshots with white borders look broken.
- Transparent PNGs: add a subtle background or padding to your logo. A
#ffffffrounded-rect behind your logo survives inversion better than a bare transparent PNG. - Dark-aware images: use the media query to swap
display: noneanddisplay: blockon two image versions — one for light, one for dark. - Screenshots: add a 1-2px solid border around screenshots so they don't bleed into the email background in either mode.
<!-- Light mode logo (hidden in dark) -->
<img src="logo-dark.png" class="light-logo"
style="display: block;" alt="Acme" />
<!-- Dark mode logo (hidden in light) -->
<img src="logo-light.png" class="dark-logo"
style="display: none;" alt="Acme" />
<style>
@media (prefers-color-scheme: dark) {
.light-logo { display: none !important; }
.dark-logo { display: block !important; }
}
</style>React Email implementation
React Email renders to HTML, so your dark mode strategy is the same as raw HTML email — but you can encapsulate it into reusable components. Here's a practical setup:
import { Head } from "@react-email/components";
export function DarkModeHead() {
return (
<Head>
<meta name="color-scheme" content="light dark" />
<meta name="supported-color-schemes" content="light dark" />
<style dangerouslySetInnerHTML={{ __html: `
@media (prefers-color-scheme: dark) {
.email-bg { background-color: #1a1a2e !important; }
.email-text { color: #e0e0e0 !important; }
.email-muted { color: #a0a0b0 !important; }
.email-card { background-color: #2d2d44 !important; }
.email-btn { background-color: #f59e0b !important;
color: #1a1a2e !important; }
}
`}} />
</Head>
);
}Then use it in your email templates alongside class names that map to both light and dark styles:
import {
Html, Body, Container, Section, Text, Button,
} from "@react-email/components";
import { DarkModeHead } from "./components/dark-mode-head";
export default function WelcomeEmail({ name }: { name: string }) {
return (
<Html>
<DarkModeHead />
<Body
className="email-bg"
style={{ backgroundColor: "#f5f5f5", margin: 0 }}
>
<Container style={{ maxWidth: 560, margin: "0 auto" }}>
<Section
className="email-card"
style={{
backgroundColor: "#ffffff",
borderRadius: 8,
padding: 32,
}}
>
<Text
className="email-text"
style={{ color: "#1a1a1a", fontSize: 16 }}
>
Welcome, {name}. Your account is ready.
</Text>
<Button
className="email-btn"
href="https://app.example.com"
style={{
backgroundColor: "#f59e0b",
color: "#1a1a1a",
padding: "12px 24px",
borderRadius: 6,
}}
>
Open dashboard
</Button>
</Section>
</Container>
</Body>
</Html>
);
}style for light mode (the default) and use className for the dark mode media query overrides. Inline styles are your light mode baseline; classes are your dark mode layer.Testing: what to check and where
You do not need to test every email client. Focus on the ones your audience actually uses, and cover the three inversion categories.
Minimum test matrix
- Apple Mail (macOS): full media query support. If it looks right here, your CSS is correct.
- Gmail (Android or iOS app): partial auto-inversion. Check that text is readable and buttons are visible.
- Outlook (Windows desktop): ignores your dark mode CSS. Check that your light mode defaults are solid enough to survive Outlook's rewrite.
- Gmail (web, dark mode): uses partial inversion. Transparent logos and light borders are the main failure points.
@media (prefers-color-scheme: dark) entirely and applies its own color transformations. Your best defense is solid light mode defaults with enough contrast to survive inversion.Common gotchas
- Gmail strips
<style>blocks in some contexts — your inline styles are the only guarantee. - Outlook ignores
border-radius, so your rounded buttons will look square — plan accordingly. - Yahoo Mail supports dark mode media queries but has unique rendering quirks with nested tables.
- Samsung Mail auto-inverts aggressively — similar to Gmail Android but with different color mapping.
Minimum viable dark mode (start here)
If you want dark mode support that covers 80% of cases with 20% of the effort, do exactly this:
The minimum viable approach: add the color-scheme meta tags, use off-white/near-black instead of pure white/black, put a solid background behind your logo, and add a 1px border around images. Skip the full media query approach unless your brand guidelines demand pixel-perfect dark mode.
- Add both
color-schememeta tags in your<head> - Replace
#ffffffbackgrounds with#f5f5f5 - Replace
#000000text with#1a1a1a - Give your logo a solid background or white padding
- Test in Apple Mail (dark) + Gmail (Android, dark) + Outlook desktop
That's it. You'll handle the majority of dark mode users without writing a single media query. Graduate to the full approach when you have time and a real need for it.