Fixing Dark-Mode Logo Inversion in Outlook and Apple Mail
Stop Outlook.com and Apple Mail dark mode from inverting your dark logo into an unreadable shape, using picture media queries, data-ogsc selectors, and background plates.
Your dark, transparent-PNG logo looks crisp in light mode, but in Outlook.com dark mode and Apple Mail dark mode it turns into a pale smear or vanishes entirely against the dark canvas. This guide isolates why those clients repaint your image and ships the exact asset-swap pattern that keeps the mark readable everywhere.
Root cause: client-side color remapping of images
Dark mode in email is not a CSS feature you opt into — it is a transformation the client runs over your markup. Two distinct mechanisms damage logos:
- Apple Mail and iOS Mail honor your authored dark styles through
@media (prefers-color-scheme: dark), but if you ship a single dark-on-transparent PNG they leave the image pixels untouched while flipping the surrounding background to near-black. A black wordmark on a transparent background then sits on a black plate and disappears. - Outlook.com (web) and Outlook for Windows/mobile go further: they apply a partial-invert heuristic. The engine samples your background and text colors and remaps them toward a dark palette. Light backgrounds become dark, dark text becomes light — but images get inconsistent treatment. A logo with fine dark detail can be partially inverted into a muddy gray shape, or recolored so the brand mark no longer matches the company colors.
The failure is deterministic per client: the pixels never change in Apple Mail (so dark detail vanishes on dark), and they get heuristically remapped in Outlook (so dark detail mangles). The fix has to address both: serve a light-on-transparent logo variant when dark mode is active, and give Outlook a surface it will not invert. For the broader theory behind these repaint passes, see the parent reference on dark mode email CSS; the layout-level rules tie back into Mastering Email HTML & CSS.
The exact fix: a <picture> swap plus an Outlook attribute override
The most robust pattern combines three layers. Each layer targets a different client family, and they are designed to be mutually non-destructive — a client that ignores one layer falls through to the next.
<!-- Layer 1: Apple Mail / iOS Mail honor prefers-color-scheme inside <picture>.
The <source> is selected before download, so only the right asset loads. -->
<picture>
<!-- Apple Mail 13+ / iOS Mail: serves the LIGHT logo in dark mode -->
<source srcset="https://cdn.example.com/logo-light.png"
media="(prefers-color-scheme: dark)">
<!-- Default for light mode and any client that ignores <source> (Gmail, Outlook) -->
<img src="https://cdn.example.com/logo-dark.png"
width="180" height="40" alt="Acme"
style="display:block;border:0;outline:none;text-decoration:none;">
</picture>
<picture> is the clean win for Apple Mail and iOS Mail because the client resolves the <source> before fetching bytes — there is no flash and no double download. Gmail and Outlook ignore <picture> entirely and render the inner <img>, which is exactly what you want in light mode.
For Outlook.com's invert heuristic, <picture> is not enough. Outlook.com rewrites your DOM and exposes its dark-mode state through generated attributes you can target with attribute selectors in a <style> block:
<style>
/* Outlook.com (web) sets data-ogsc on elements whose foreground (text/SVG)
color it has remapped, and data-ogsb where it remapped a background.
"ogsc" = Outlook Generated Style Color, "ogsb" = ...Background. */
/* Hide the dark logo and show the light one ONLY inside Outlook.com dark mode */
[data-ogsc] .dark-logo { display: none !important; } /* Outlook.com: kill dark asset */
[data-ogsc] .light-logo { display: inline-block !important; } /* Outlook.com: reveal light asset */
/* Force the plate behind the logo to stay a fixed dark color Outlook will not re-remap.
data-ogsb wraps the cell whose background Outlook already touched. */
[data-ogsb] .logo-plate { background-color: #1f2330 !important; } /* Outlook.com: lock plate color */
/* Apple Mail / iOS Mail path (Outlook never reads this media query). */
@media (prefers-color-scheme: dark) {
.dark-logo { display: none !important; } /* Apple Mail: hide dark asset */
.light-logo { display: inline-block !important; } /* Apple Mail: show light asset */
.logo-plate { background-color: #1f2330 !important; }
}
</style>
The markup the selectors hook into uses a .dark-img / .light-img swap, with the light variant hidden by default and an MSO conditional comment so the Outlook for Windows (Word engine) desktop client — which does not honor either mechanism — never downloads the second image:
<table role="presentation" class="logo-plate"
style="background-color:#ffffff;border-radius:8px;" cellpadding="0" cellspacing="0">
<tr>
<td style="padding:16px 24px;">
<!-- Default / light-mode asset. Shown by Gmail, Outlook desktop, light Apple Mail. -->
<img class="dark-logo" src="https://cdn.example.com/logo-dark.png"
width="180" height="40" alt="Acme"
style="display:block;border:0;">
<!--[if !mso]><!-->
<!-- Light-mode-on-dark asset. Hidden by default; revealed only by the
dark-mode rules above. The mso guard stops Outlook desktop (Word engine)
rendering BOTH logos stacked, since it ignores display:none from <style>. -->
<img class="light-logo" src="https://cdn.example.com/logo-light.png"
width="180" height="40" alt="Acme"
style="display:none;border:0;mso-hide:all;">
<!--<![endif]-->
</td>
</tr>
</table>
The background-color:#ffffff on the plate gives the logo a solid padded background in light mode. In dark mode the rules repaint that plate to #1f2330, which is light enough to keep a light wordmark crisp but dark enough to read as "dark mode." Because the color is set explicitly and re-asserted under [data-ogsb], Outlook stops applying its own guesswork to it.
Variant: Gmail app versus Apple Mail
Not every client deserves the same effort, because their dark-mode capabilities differ sharply:
- Apple Mail / iOS Mail are the high-fidelity targets. They fully support
prefers-color-schemeand<picture>media, so the asset swap is clean and the light logo loads only when needed. Test these first. - The Gmail app has limited and inconsistent dark support. On many builds it does a blanket invert with no hook you can target, and it strips
<style>blocks for non-Gmail accounts (see fixing Gmail app media-query stripping for the mechanics). For Gmail the realistic defense is the solid padded plate: a logo on its own opaque background tile resists most blanket inversions because the client inverts plate and logo together, preserving their relative contrast. Ship a logo whose lockup already includes its background so a single inversion still reads.
Practically: rely on the asset swap for Apple Mail, and rely on a baked-in opaque background for Gmail. The two strategies coexist in the same markup.
Variant: a single multicolor logo you cannot recolor
Asset swapping assumes you can produce a clean light-on-transparent variant. A full-color brand mark (a photographic badge, a gradient lockup) has no obvious "light version." Here the durable fix is the opaque rounded plate: give the logo its own fixed background tile that contrasts in both themes, then lock that tile's color so neither Apple Mail nor Outlook.com repaints it.
<table role="presentation" class="logo-plate" cellpadding="0" cellspacing="0"
style="background-color:#ffffff;border-radius:8px;">
<tr>
<td style="padding:14px 22px;">
<img src="https://cdn.example.com/logo-color.png" width="180" height="40" alt="Acme"
style="display:block;border:0;">
</td>
</tr>
</table>
/* Keep the plate a light, fixed tone in BOTH modes so the multicolor mark always
sits on the contrast it was designed for. */
[data-ogsb] .logo-plate { background-color:#ffffff !important; } /* Outlook.com: stop plate remap */
@media (prefers-color-scheme: dark) {
.logo-plate { background-color:#ffffff !important; } /* Apple Mail / iOS Mail */
}
Because the plate stays white in dark mode, the full-color mark reads exactly as designed and you never need a second asset. The trade-off is a visible light card in an otherwise dark email — acceptable for a header lockup, less so for an inline icon.
Variant: SVG logos and data-ogsc foreground remapping
If you embed the logo as inline SVG (supported by Apple Mail and iOS Mail, stripped by Gmail and Outlook desktop), Outlook.com treats the SVG fill as a foreground color and stamps [data-ogsc] on it, remapping a dark fill toward light. Pin the fill back explicitly:
[data-ogsc] .logo-svg path { fill:#FFA5AB !important; } /* Outlook.com: re-pin SVG fill */
@media (prefers-color-scheme: dark) {
.logo-svg path { fill:#FFA5AB !important; } /* Apple Mail / iOS Mail */
}
Always pair inline SVG with a PNG fallback through the same <picture>/class-toggle mechanism, since Gmail and Windows Outlook will not render the SVG at all. The broader theory of why these foreground/background attributes appear is in the parent dark mode email CSS reference.
Variant: dark-on-dark in the Gmail Android app
The Gmail app on Android frequently applies a blanket invert with no [data-ogsc] hook and a stripped <style> block for IMAP accounts. Neither the <picture> swap nor the attribute selectors fire. The only reliable defense is the baked-in opaque plate from the first variant above: because Gmail inverts plate and logo together, their relative contrast is preserved through a single blanket inversion. Ship the lockup-with-background asset and accept that fine-grained per-theme control is not available on that client.
Pipeline integration
Treat the light variant as a first-class build artifact, not a manual export:
- Generate
logo-light.pngfrom the same source aslogo-dark.pngduring asset build (a single ImageMagick/sharprecolor step), so they never drift in size or padding. - Inline the dark-mode
<style>block through your build but keep it in the document head — do not let the inliner flatten it. If you use Juice, confirm the attribute selectors survive by following preserving media queries when inlining with Juice. - Pin absolute CDN URLs (no relative paths) and set long cache headers so the swap is instant on repeat opens.
- Add a snapshot of both logo assets to your QA fixtures so a logo redesign forces a regeneration of the light variant.
Wiring the swap into a CI build
Make the two-asset invariant enforceable rather than a convention an engineer can forget. A guard step in CI catches a missing or misaligned variant before it ships:
// ci-logo-variants.js — fail the build if the dark/light logo pair drifts
const sharp = require('sharp');
(async () => {
const dark = await sharp('assets/logo-dark.png').metadata();
const light = await sharp('assets/logo-light.png').metadata();
// Apple Mail / iOS Mail rely on identical width/height attributes across variants;
// a size mismatch causes a visible jump when the <source> swaps in dark mode.
if (dark.width !== light.width || dark.height !== light.height) {
throw new Error(`Logo variant size mismatch: dark ${dark.width}x${dark.height} vs light ${light.width}x${light.height}`);
}
console.log('Logo variants aligned:', dark.width + 'x' + dark.height);
})();
Beyond the size guard, fold the rendered check into your snapshot stage: capture the header region in Outlook.com, Apple Mail, iOS Mail, and the Gmail app under dark mode, and diff against an approved baseline so a future template change that drops mso-hide:all or the [data-ogsb] rule fails the merge instead of reaching production. Because the same [data-ogsc]/[data-ogsb] machinery governs every remapped element, this fixture doubles as a regression net for the whole header — re-pinned text colors and accent fills are validated in the same pass. For the upstream rules these snapshots depend on, keep the dark-mode <style> intact through inlining as described in the parent dark mode email CSS guide.
Validation checklist
Frequently Asked Questions
Why does the logo vanish rather than invert?
Because the client repaints the surrounding surface and leaves the image pixels alone. A dark mark on a transparent background then sits on a dark plate — nothing inverted, the contrast simply disappeared. That is why an asset swap fixes it and a CSS filter usually does not.
Does <picture> work in Outlook?
No. Outlook ignores <source> and renders the inner <img>, which is the correct behaviour for the light asset and the reason <picture> is safe to use: clients that do not understand it fall through to the default rather than showing nothing. Outlook.com needs the attribute-selector path instead.
Should the light logo be white or brand-coloured?
Whatever keeps the mark recognisable against a dark surface, which for most brands is a white or very light version rather than a recoloured one. A brand colour chosen for white backgrounds usually lacks contrast on near-black, and re-tinting a logo is a brand decision rather than a technical one — worth agreeing before the template needs it.
Can we avoid the whole problem with an opaque plate?
Often, yes, and it is the more robust answer where a swap is impractical. A logo on an explicitly white padded cell renders identically in every client because there is no transparency for an inversion heuristic to act on. The cost is a visible white block in an otherwise dark message, which some designs accept and others do not.
Does this affect SVG logos?
More so, because some clients recolour SVG fills through the same mechanism they use for text. Where an SVG is used, treat it as the fragile case: serve a PNG variant for email, or plate it. Support for SVG in email is patchy enough that it is rarely worth the argument.
Related
- Dark mode email CSS — the full set of color-scheme techniques this logo fix is part of
- Fixing Gmail app media-query stripping — why Gmail drops the
<style>block your swap relies on - Preserving media queries when inlining with Juice — keep the dark-mode rules alive through your build
- Mastering Email HTML & CSS — layout and rendering fundamentals across clients
← Back to Dark Mode Email CSS