Everything you know about color in CSS mostly does not apply in email. No custom properties in several major clients, dark mode that rewrites your palette without asking, and a rendering engine in Outlook that is closer to a word processor than a browser. Email color is its own discipline, and most of its rules exist because a specific client does something specific and unhelpful.

Why email is different

A web page runs in one engine you can test. An email lands in dozens of clients — desktop Outlook, Outlook on the web, Apple Mail, Gmail's web interface, Gmail's apps, Yahoo, Samsung Mail, and more — each stripping, rewriting or ignoring different parts of your CSS.

Two consequences drive everything below. Support skews old and inconsistent, so you write conservative CSS. And several clients actively modify your colors for dark mode, which means the palette that arrives is not always the one you sent.

Use inline styles and HEX

Gmail strips <style> blocks in several contexts, particularly when forwarding. The reliable approach is inline styles on the elements themselves:

<td style="background-color:#3B82F6; color:#FFFFFF;">

Write colors as six-digit HEX. Not three-digit shorthand, which some older clients mishandle. Not rgb(), and certainly not hsl() — support is patchy and the failure mode is a missing background rather than a fallback.

Custom properties are effectively unusable. Where a variable is unsupported the declaration is dropped, and the element gets a transparent background. Build your palette in a template system that inlines literal values at send time — the HEX to RGB converter is useful for keeping a table of the values you are inlining, but ship the HEX.

Always set background and text color together

This is the rule that prevents the most common catastrophic failure: white text on a background that did not render, producing an invisible message.

Any time you set one, set the other:

<!-- fragile -->
<td style="background-color:#0B0F14;">
  <p style="color:#FFFFFF;">Read this</p>
</td>

<!-- safer -->
<td bgcolor="#0B0F14" style="background-color:#0B0F14; color:#FFFFFF;">
  <p style="color:#FFFFFF; background-color:#0B0F14;">Read this</p>
</td>

The bgcolor attribute is deprecated HTML and remains worth including, because some Outlook versions honour it when they ignore the CSS.

Dark mode: three different behaviours

Email clients handle dark mode in three ways, and knowing which is which explains most surprises.

No change. Some clients render your colors as sent. Nothing to do.

Partial inversion. Apple Mail and several others adjust colors they consider too light for a dark interface. Your white background may become dark gray while your dark text is lightened. Usually reasonable, occasionally wrong — a light gray box designed to be subtle can become a dark box that now reads as emphasis.

Full forced inversion. Some Outlook versions invert aggressively, which is where designs break. A carefully built palette can arrive with mismatched inverted and non-inverted regions in the same message.

Two defensive techniques help. Declare that you support both schemes, which stops some clients from applying their own transformation:

<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">

And avoid pure white and pure black. Clients tend to leave near-white and near-black values alone while aggressively rewriting the extremes. Using #FEFEFE rather than #FFFFFF is a small, widely-used hedge.

Images and logos

A logo with dark text on a transparent PNG becomes invisible on a dark background. It is the most common dark-mode email bug and the easiest to prevent.

Two fixes. Give the logo a solid background of its own — a white pill or rounded rectangle — so it carries its own contrast wherever it lands. Or ship a light variant and swap it with a media query in the clients that support one, keeping the safe version as the default.

Also assume images may not load at all. Many clients block remote images until the reader opts in, so a message whose entire design lives in one image arrives as an empty box. Set a background color on the containing cell so blocked images degrade to a colored area rather than a white void, and write real alt text.

Buttons: build them from HTML, not images

An image button fails when images are blocked and looks wrong at high pixel density. Build buttons from a table cell with a background color and a styled link:

<table role="presentation" cellpadding="0" cellspacing="0">
  <tr>
    <td bgcolor="#3B82F6" style="background-color:#3B82F6; border-radius:6px;">
      <a href="https://example.com"
         style="display:inline-block; padding:12px 24px;
                color:#FFFFFF; text-decoration:none; font-weight:600;">
        Get started
      </a>
    </td>
  </tr>
</table>

Set the color on the anchor itself. Some clients override unstyled link colors with their own default blue, and a blue link on a blue button is unreadable.

Gradients rarely survive

Desktop Outlook does not support CSS gradients. If you use one, always set a solid background-color first as a fallback, so unsupported clients get a usable flat color rather than nothing:

<td style="background-color:#3B82F6;
           background-image:linear-gradient(135deg,#3B82F6,#A855F7);">

Pick the fallback as the color that keeps your text readable, not necessarily the first gradient stop. Our post on CSS gradients covers picking stops; in email the fallback matters more than the gradient.

Contrast still applies, and matters more

Email is read on phones, in bright sunlight, on old screens, by people scanning quickly. The WCAG thresholds — 4.5:1 for body text — are a floor, not a target.

Check every pair before sending, including the states you might not have thought about: text over a background image, the button label against the button, footer text against the footer background (a perennial failure — small gray legal text on light gray is close to universal and close to unreadable). Run them through the contrast checker.

And because some clients modify colors for dark mode, check the inverted version too where you can. Our accessible color guide covers the thresholds in full.

A pre-send checklist

  1. All colors are six-digit HEX, inlined on the elements.
  2. Every element setting a text color also sets a background color, and vice versa.
  3. bgcolor attributes accompany background-color styles on table cells.
  4. color-scheme meta tags are present.
  5. Pure #FFFFFF and #000000 avoided in favour of near values.
  6. Logo works on both light and dark backgrounds.
  7. Buttons are HTML, with the link color set explicitly.
  8. Gradients have a solid fallback.
  9. The design is readable with images blocked.
  10. Every text pair clears 4.5:1.

Then test on real clients. Email is the one place where "it works in my browser" carries almost no information at all.