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
@mediaqueries andcolor-scheme. - Gmail (web + mobile) — ~28% market share. Strips
<style>blocks in some contexts, forces inline styles, removes@importand 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.
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.
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.
- 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
- 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.
<!--[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]-->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.
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'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's what'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 devand 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:
- Gmail web (Chrome) — Send yourself a real email and check it. Gmail's preview is accurate.
- Apple Mail (macOS or iOS) — If it looks good here, it'll look good in most webkit-based clients.
- 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.
- Mobile (iOS Mail or Gmail app) — Check on a real phone. Simulators miss touch-target sizing issues.
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
Containerfor max-width: It generates the MSO table wrapper automatically. Don't use a raw<div>withmax-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/Columnfor multi-column: They generate table markup. Raw flexbox divs break in Outlook. - Set explicit widths on images: Use the
widthandheightprops onImg. Without them, some clients render images at their native resolution, blowing out your layout. - Include a
Previewcomponent: 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
Buttonin Outlook: React Email'sButtonuses VML for Outlook compatibility. Verify the border-radius and padding render correctly. - Use system fonts: Set your
fontFamilytosystem-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.
render() and measure the byte length.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