Templates13 min read

Email Client Compatibility Testing: A Practical Guide for 2026

Gmail, Outlook, and Apple Mail render emails differently. Learn which CSS features break, how to build defensive layouts, and a testing workflow that catches issues before users do.

R

React Emails Pro

March 17, 2026

Your email looks perfect in Gmail. You ship it. Then a customer on Outlook screenshots what they received and it looks like a ransom note — broken columns, missing images, text overlapping buttons.

Email client rendering is the web development equivalent of browser compatibility testing in 2008, except worse. There's no shared rendering engine, no standards body with enforcement power, and Microsoft decided that Word's HTML renderer was good enough for Outlook.

This guide covers which clients matter in 2026, what breaks across them, and how to build emails that render correctly everywhere without losing your mind.

15,000+

Email client and device combinations

Litmus, 2025 Email Client Market Report

41%

Emails opened on mobile

Varies by industry — B2B skews desktop

28%

Outlook users see broken CSS Grid layouts

Outlook uses Word's HTML engine on Windows


The email client landscape in 2026

Not every client matters equally. Your testing priority should match your audience's actual client distribution. If you don't have that data yet, here's the general market breakdown for B2B SaaS.

Tier 1: test every email here

  • Apple Mail (macOS + iOS) — ~35% market share. Best rendering engine. Supports most modern CSS including @media queries and color-scheme.
  • Gmail (web + mobile) — ~28% market share. Strips <style> blocks in some contexts, forces inline styles, removes @import and custom fonts.
  • Outlook (Windows) — ~10% market share but dominant in enterprise B2B. Uses Word's HTML rendering engine. This is where most layouts break.

Tier 2: test for important sends

  • Yahoo Mail — ~5%. Decent rendering, but strips some CSS properties and has quirks with background images.
  • Outlook (macOS / web) — Different rendering engine than Windows Outlook. Much better CSS support, closer to Apple Mail.
  • Samsung Mail — ~3%. Android default mail app on Samsung devices. Rendering is acceptable but occasionally clips long emails.
If you're sending transactional emails to developers (SaaS auth, API notifications), your audience skews heavily toward Apple Mail and Gmail. Outlook testing is still worth it — you never know when a developer's finance team forwards your invoice email.

The 5 CSS features that break across clients

Most email rendering bugs come from using CSS features that work in browsers but not in email clients. Here are the specific properties to watch.

1. Flexbox and CSS Grid

Neither works in Outlook on Windows. Apple Mail and Gmail web support flexbox. No email client reliably supports CSS Grid.

If you use display: flex or display: grid for layout, Outlook users see a single stacked column with no spacing. Use tables or mso- conditional comments for multi-column layouts.

2. Media queries

Gmail's mobile app ignores @media queries entirely. Gmail web supports them in <style> blocks but strips them from <link> tags. Apple Mail has full support.

The practical impact: you can't rely on media queries for responsive design in Gmail mobile. Build your base layout to be fluid (percentage widths), then enhance with media queries for clients that support them.

3. Custom fonts

@font-face and @import for Google Fonts work in Apple Mail only. Every other major client falls back to system fonts. Don't design your email around a custom font — design it to look good with the fallback stack.

4. Background images

background-image on <div> elements doesn't render in Outlook Windows. You need VML (Vector Markup Language) fallbacks wrapped in MSO conditional comments.

5. Max-width

Outlook ignores max-width on <div> elements. Your 600px centered container will stretch to fill the viewport. Fix this with a wrapping table or MSO conditional.


Building a defensive email CSS strategy

The email development community has settled on a pragmatic approach: build with modern markup (React Email components, semantic HTML), then add targeted fallbacks for Outlook using MSO conditional comments.

Defensive approach
  • Use React Email's layout components (Container, Section, Row, Column)
  • Set widths with inline styles, not just CSS classes
  • Add MSO conditionals for Outlook table fallbacks
  • Design for fluid layouts first, enhance with media queries
  • Test with system font stack, treat custom fonts as progressive enhancement
CSS-first approach
  • Use flexbox or CSS Grid for multi-column layouts
  • Rely on max-width without table fallbacks
  • Depend on media queries for core responsive behavior
  • Use background-image without VML fallbacks
  • Assume custom fonts will render

MSO conditional comments for Outlook

MSO conditionals are HTML comments that only Outlook's Word-based renderer interprets. Use them to wrap table-based fallback layouts.

mso-conditional-wrapper.html
<!--[if mso]>
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="600" align="center">
  <tr>
    <td width="280" valign="top">
<![endif]-->

<div style="display: inline-block; max-width: 280px; width: 100%; vertical-align: top;">
  <!-- Left column content -->
</div>

<!--[if mso]>
    </td>
    <td width="40"></td>
    <td width="280" valign="top">
<![endif]-->

<div style="display: inline-block; max-width: 280px; width: 100%; vertical-align: top;">
  <!-- Right column content -->
</div>

<!--[if mso]>
    </td>
  </tr>
</table>
<![endif]-->
If you're using React Email, most of this is handled for you. The Row and Column components generate the MSO fallbacks automatically. The main exception is custom layouts that don't fit the Row/Column pattern.

A responsive layout that works everywhere

Here's a pattern using React Email components that renders correctly in Gmail, Outlook, and Apple Mail. It uses Section for the wrapper, Row and Column for multi-column layout, and inline styles for reliable rendering.

components/two-column-layout.tsx
import {
  Html,
  Head,
  Body,
  Container,
  Section,
  Row,
  Column,
  Text,
  Button,
  Img,
  Preview,
} from "@react-email/components";

interface FeatureEmailProps {
  userName: string;
  features: Array<{ title: string; description: string }>;
}

export function FeatureAnnouncementEmail({
  userName,
  features,
}: FeatureEmailProps) {
  return (
    <Html>
      <Head />
      <Preview>New features just shipped — here&apos;s what changed</Preview>
      <Body style={{ backgroundColor: "#f9fafb", fontFamily: "system-ui, sans-serif" }}>
        <Container style={{ maxWidth: "600px", margin: "0 auto", padding: "40px 20px" }}>
          {/* Single-column header — works everywhere */}
          <Section style={{ backgroundColor: "#ffffff", borderRadius: "8px", padding: "32px" }}>
            <Text style={{ fontSize: "20px", fontWeight: "600", color: "#111827" }}>
              Hey {userName}, we shipped new features
            </Text>
            <Text style={{ fontSize: "15px", color: "#6b7280", lineHeight: "1.6" }}>
              Here&apos;s what&apos;s new this week.
            </Text>
          </Section>

          {/* Two-column feature grid — Row/Column handles MSO fallback */}
          <Section style={{ marginTop: "16px" }}>
            <Row>
              {features.slice(0, 2).map((feature, i) => (
                <Column
                  key={i}
                  style={{
                    width: "50%",
                    padding: "8px",
                    verticalAlign: "top",
                  }}
                >
                  <div style={{
                    backgroundColor: "#ffffff",
                    borderRadius: "8px",
                    padding: "20px",
                  }}>
                    <Text style={{ fontSize: "15px", fontWeight: "600", color: "#111827" }}>
                      {feature.title}
                    </Text>
                    <Text style={{ fontSize: "13px", color: "#6b7280", lineHeight: "1.5" }}>
                      {feature.description}
                    </Text>
                  </div>
                </Column>
              ))}
            </Row>
          </Section>

          {/* Single CTA — always at the bottom */}
          <Section style={{
            backgroundColor: "#ffffff",
            borderRadius: "8px",
            padding: "24px",
            marginTop: "16px",
            textAlign: "center" as const,
          }}>
            <Button
              href="https://app.yourproduct.com/changelog"
              style={{
                backgroundColor: "#111827",
                color: "#ffffff",
                padding: "12px 32px",
                borderRadius: "6px",
                fontSize: "15px",
                fontWeight: "500",
                textDecoration: "none",
              }}
            >
              See full changelog
            </Button>
          </Section>
        </Container>
      </Body>
    </Html>
  );
}

The key pattern: Row and Column produce table markup that Outlook understands, while the inline styles ensure Gmail doesn't strip your layout. The outer Container with maxWidth constrains the width in clients that support it.


Testing workflow: tools and automation

Manual testing across 15 email clients is not sustainable. Here's a practical workflow that balances coverage with speed.

Tools worth paying for

  • Litmus — Screenshots across 90+ clients. Expensive but comprehensive. Best for teams sending high-volume marketing emails.
  • Email on Acid — Similar to Litmus, slightly cheaper. Good accessibility checker built in.
  • React Email preview server — Free and built into your dev workflow. Run email dev and iterate on templates in the browser. Doesn't test real client rendering, but catches most markup issues.

The minimum viable testing checklist

If you can't justify Litmus pricing, test manually in these four environments:

  1. Gmail web (Chrome) — Send yourself a real email and check it. Gmail's preview is accurate.
  2. Apple Mail (macOS or iOS) — If it looks good here, it'll look good in most webkit-based clients.
  3. Outlook on Windows — Use the Outlook web app (outlook.live.com) as a proxy if you don't have a Windows machine. Not identical to desktop Outlook, but catches the worst rendering issues.
  4. Mobile (iOS Mail or Gmail app) — Check on a real phone. Simulators miss touch-target sizing issues.
Automate the send step. Set up a test route in your app that triggers each email type to a list of test addresses (one per client). Run it before every template change ships to production.

React Email compatibility checklist

React Email handles many cross-client issues automatically, but there are still patterns that cause problems. Run through this before deploying any template.

  • Use Container for max-width: It generates the MSO table wrapper automatically. Don't use a raw <div> with max-width.
  • Inline all styles: React Email does this automatically at render time. Don't add a separate <style> block expecting it to work in Gmail.
  • Use Row/Column for multi-column: They generate table markup. Raw flexbox divs break in Outlook.
  • Set explicit widths on images: Use the width and height props on Img. Without them, some clients render images at their native resolution, blowing out your layout.
  • Include a Preview component: Controls the inbox preview text. Without it, clients pull the first text content they find, which is often “View in browser” or your logo alt text.
  • Test Button in Outlook: React Email's Button uses VML for Outlook compatibility. Verify the border-radius and padding render correctly.
  • Use system fonts: Set your fontFamily to system-ui, -apple-system, sans-serif. Custom fonts are ignored by most clients.
  • Keep total HTML under 102KB: Gmail clips emails larger than this, hiding everything after the cutoff behind a “View entire message” link.
Gmail's 102KB clipping limit is on the rendered HTML, not your source code. React Email's rendering adds wrapper elements and inline styles that increase size. Check the output with render() and measure the byte length.

Key takeaway

Email client compatibility checklist:

  • Test in Gmail, Apple Mail, Outlook (Windows), and mobile as a minimum
  • Never use flexbox or CSS Grid for layout — use Row/Column or tables
  • Add MSO conditionals for Outlook-specific fallbacks
  • Keep rendered HTML under 102KB to avoid Gmail clipping
  • Set explicit image dimensions to prevent layout blowouts
  • Use system fonts — treat custom fonts as progressive enhancement
  • Automate test sends before every production deploy
R

React Emails Pro

Team

Building production-ready email templates with React Email. Writing about transactional email best practices, deliverability, and developer tooling.

Production-ready templates

Pick from 9 template packs built with React Email. One-time purchase, lifetime updates, tested across every major email client.

Browse all templates