Responsive
About 60-70% of email opens happen on mobile. The web-style “responsive” approach — media queries that swap layouts at breakpoints — works in modern clients, but Outlook for Windows ignores media queries entirely. The reliable pattern is hybrid responsive: build a layout that works at any width by default, and use media queries only as enhancement.
The 3-table-level wrapper (start here)
Section titled “The 3-table-level wrapper (start here)”Every responsive-safe email uses the same three nested table levels. Get this right and most mobile bugs disappear before you write a media query.
<!-- LEVEL 1: OUTER wrapper. Full viewport width. Page background goes here. --><table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="width:100%;background-color:#F5F5F5;"> <tr> <td align="center" style="padding:20px 10px;">
<!-- LEVEL 2: CONTAINER. 600px desktop, fluid on mobile. ONLY level with a fixed width. --> <!--[if mso | IE]> <table role="presentation" align="center" width="600" cellpadding="0" cellspacing="0" border="0"> <tr><td> <![endif]--> <table role="presentation" cellpadding="0" cellspacing="0" border="0" style="max-width:600px;width:100%;margin:0 auto;background-color:#FFFFFF;"> <tr> <td>
<!-- LEVEL 3: INNER content tables. Always width="100%". NEVER 600. --> <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%"> <tr> <td>Header content</td> </tr> </table>
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%"> <tr> <td>Body content</td> </tr> </table>
</td> </tr> </table> <!--[if mso | IE]> </td></tr> </table> <![endif]-->
</td> </tr></table>Three rules to keep in your head:
- OUTER is
width="100%". It’s the page background, edge-to-edge. - CONTAINER is the only place a fixed
600shows up — and it’s inside the MSO conditional. Modern clients see onlymax-width:600px;width:100%, so they shrink it on narrow viewports. - INNER content tables are
width="100%"— neverwidth="600". Hardcoding600on inner tables is the #1 cause of horizontal scroll on mobile.
Most of the rest of this page is variations on this base. If you’re getting horizontal scroll at 320-400px, the first thing to check is whether an inner table inherited width="600".
The two strategies
Section titled “The two strategies”Strategy 1 — Media queries (modern clients)
Section titled “Strategy 1 — Media queries (modern clients)”<style> blocks in the <head> work in Apple Mail, Gmail web, Outlook.com, mobile clients. They do NOT work in Outlook desktop (Windows). For any client that supports them, this is the cleanest pattern:
<style> @media only screen and (max-width: 600px) { .email-container { width:100% !important; } .stack-column { display:block !important; width:100% !important; } .stack-column img { width:100% !important; height:auto !important; } .mobile-hidden { display:none !important; } .mobile-only { display:block !important; } .mobile-padding { padding:16px !important; } }</style>Then mark each element you want to behave responsively with a class:
<table class="email-container" width="600"> <tr> <td class="stack-column" width="50%">Column 1</td> <td class="stack-column" width="50%">Column 2</td> </tr></table>Strategy 2 — Hybrid (works in Outlook desktop too)
Section titled “Strategy 2 — Hybrid (works in Outlook desktop too)”The hybrid approach builds a fluid layout using max-width + ghost tables. Even without media queries, the email collapses cleanly when the viewport is narrow:
<!--[if mso]><table role="presentation" width="600" align="center" border="0" cellspacing="0" cellpadding="0"><tr><td width="300" valign="top"><![endif]-->
<div style="display:inline-block; width:100%; max-width:300px; vertical-align:top;"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td>Column 1 content</td> </tr> </table></div>
<!--[if mso]></td><td width="300" valign="top"><![endif]-->
<div style="display:inline-block; width:100%; max-width:300px; vertical-align:top;"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td>Column 2 content</td> </tr> </table></div>
<!--[if mso]></td></tr></table><![endif]-->This produces:
- Outlook desktop: sees the MSO ghost table → renders two 300px columns side-by-side.
- Every other client: sees the inline-block
<div>s → they sit side-by-side when the viewport is ≥600px, stack vertically when narrower (becausemax-width:300pxlets them shrink to 100% wrapping).
The hybrid approach works without ANY media query.
The 600px breakpoint
Section titled “The 600px breakpoint”Email is conventionally designed at 600px wide because:
- Outlook desktop reading panes default to ~575-625px.
- Most webmail apps cap the rendered email at 600-700px even on wide screens.
- Mobile phones in portrait are 320-440px — narrow enough that 600px content needs to scale or stack.
Some templates use 640px or 680px; this is fine as long as you’re consistent. Going wider than 700px usually means horizontal scroll on the reading pane.
Single-column collapse
Section titled “Single-column collapse”The most common responsive change: two side-by-side columns become two stacked rows on mobile.
Via media query (modern clients only)
Section titled “Via media query (modern clients only)”<style> @media only screen and (max-width: 480px) { .stack { display:block !important; width:100% !important; } }</style>
<table width="600"> <tr> <td class="stack" width="300">Column 1</td> <td class="stack" width="300">Column 2</td> </tr></table>Via hybrid pattern (Outlook-safe)
Section titled “Via hybrid pattern (Outlook-safe)”Use the inline-block <div> approach from above. The columns naturally stack when they can no longer sit side-by-side without overflowing.
Mobile-specific styles
Section titled “Mobile-specific styles”When you want to apply styles ONLY on mobile, use a media query targeting your breakpoint:
<style> @media only screen and (max-width: 480px) { /* Bigger touch targets for buttons */ .mobile-button { width:100% !important; max-width:none !important; font-size:16px !important; padding:14px 20px !important; }
/* Larger body text */ .mobile-text { font-size:18px !important; line-height:28px !important; }
/* Tighter spacing */ .mobile-pad-sm { padding:16px !important; } }</style>The !important is required in all of these — without it, inline styles win over <style> block rules.
Hide on mobile / show on mobile
Section titled “Hide on mobile / show on mobile”<style> @media only screen and (max-width: 480px) { .mobile-hidden { display:none !important; } .mobile-only { display:block !important; width:100% !important; height:auto !important; max-height:none !important; visibility:visible !important; overflow:visible !important; } }</style>
<!-- Hidden on mobile --><table class="mobile-hidden"> <tr><td>Desktop-only content</td></tr></table>
<!-- Shown only on mobile --><table class="mobile-only" style="display:none; max-height:0; overflow:hidden;"> <tr><td>Mobile-only content</td></tr></table>The mobile-only block must start with display:none; max-height:0; overflow:hidden; inline — this is the “deep hide” pattern that works across Gmail and Outlook web.
Image scaling
Section titled “Image scaling”Images on responsive emails need max-width:100% in their inline style:
<img src="https://placehold.co/600x300/E0E0E0/E0E0E0" width="600" height="auto" alt="..." style="height:auto; display:block; max-width:100%;">The width="600" attribute is what desktop clients use; max-width:100% lets mobile clients shrink it down without overflowing.
For Retina-quality (sharp on high-DPI screens), serve images at 2× the displayed size. A 600px-wide hero should be a 1200px-wide source image, displayed at width 600.
The .stack padding gotcha
Section titled “The .stack padding gotcha”A subtle bug that produces horizontal scroll even when your layout looks correct. The setup looks like this:
<style> @media only screen and (max-width: 600px) { .stack { width:100% !important; display:block !important; } }</style>
<table width="600" style="max-width:600px;width:100%;"> <tr> <!-- Two columns with padding --> <td class="stack" width="50%" style="padding:20px 40px;">Column 1</td> <td class="stack" width="50%" style="padding:20px 40px;">Column 2</td> </tr></table>On mobile, the .stack rule kicks in: each <td> becomes display:block; width:100%. The padding (40px left + 40px right = 80px) is added on top of the 100% width because the default box-sizing is content-box. Result: each stacked <td> is 100% + 80px wide → horizontal scroll.
Two fixes. Pick the right one based on whether you can rely on box-sizing:
Fix 1 — Padding on an inner wrapper (recommended)
Section titled “Fix 1 — Padding on an inner wrapper (recommended)”Move the padding off the cell. Put it on a <div> inside the cell:
<style> @media only screen and (max-width: 600px) { .stack { width:100% !important; display:block !important; } }</style>
<table width="600" style="max-width:600px;width:100%;"> <tr> <td class="stack" width="50%"> <div style="padding:20px 40px;">Column 1</div> </td> <td class="stack" width="50%"> <div style="padding:20px 40px;">Column 2</div> </td> </tr></table>Works in every client. The cell is fluid; the inner <div> carries the padding without inflating the cell’s box. This is the canonical fix.
Fix 2 — calc() to subtract padding from width
Section titled “Fix 2 — calc() to subtract padding from width”If you must keep padding on the cell, subtract it explicitly:
<style> @media only screen and (max-width: 600px) { .stack { width: calc(100% - 80px) !important; display: block !important; } }</style>Brittle — you have to recompute every time padding changes, and calc() is fine in modern clients but inconsistent in older ones. Use Fix 1 when you can.
Test matrix
Section titled “Test matrix”Before sending a responsive email, test on at least:
- Mobile: iPhone Mail (iOS), Gmail iOS, Gmail Android, Outlook iOS
- Desktop webmail: Gmail web (Chrome), Outlook.com (web)
- Desktop apps: Outlook 2019 or 365 (Windows), Apple Mail (Mac)
- Dark mode: Apple Mail dark, Outlook dark, Gmail dark — see Dark Mode for the dark-specific patterns
Litmus and Email on Acid render across this matrix automatically.
Related
Section titled “Related”- Outlook & MSO — the conditional comment pattern that powers hybrid responsive
- Images —
max-width:100%and scaling - Buttons — touch-target sizing for mobile
- Dark Mode —
prefers-color-schemeworks inside@mediablocks