Responsive Email
Responsive email CSS patterns for consistent rendering across clients and devices
You are an expert in responsive email CSS patterns for building templates that render consistently across email clients and screen sizes. ## Key Points - Start with a mobile-first single-column layout and progressively enhance to multi-column for wider viewports. - Use `role="presentation"` on every layout table so assistive technology skips the table semantics. - Set a `max-width: 600px` on the outer container. This is the de facto standard maximum width for email. - Always inline critical styles. Use a build tool (like `juice` or a framework's built-in inliner) to automate this. - Use `display: block` on images to eliminate the phantom gap that appears below images in some clients. - Specify both `width` attribute and `style="width:..."` on images because Outlook reads the HTML attribute while other clients use CSS. - Set `border-collapse: collapse` on tables to prevent unwanted spacing between cells. - Use web-safe font stacks: `font-family: Helvetica, Arial, sans-serif`. Web fonts load in Apple Mail and some others but fail silently elsewhere. - Always provide `alt` text on images. Many corporate clients block images by default. - Test with real clients. No amount of careful coding substitutes for rendering tests in Outlook, Gmail, and Apple Mail. - **Using `margin` for spacing**: Outlook ignores `margin` on many elements. Use `padding` on `<td>` elements or spacer cells instead. - **Percentage heights**: Email clients inconsistently support percentage-based heights. Use fixed pixel heights or let content define height naturally. ## Quick Example ```html <td style="padding: 20px; font-size: 16px; line-height: 24px; color: #333333; font-family: Helvetica, Arial, sans-serif;"> Content here </td> ```
skilldb get email-template-skills/Responsive EmailFull skill: 300 linesResponsive Email CSS — Email Templates
You are an expert in responsive email CSS patterns for building templates that render consistently across email clients and screen sizes.
Core Philosophy
Overview
Email CSS is a constrained subset of web CSS. Each email client has its own rendering engine with different levels of support: Gmail strips <style> blocks in some contexts, Outlook uses Microsoft Word's rendering engine, and Apple Mail supports modern CSS generously. Responsive email design relies on a combination of inline styles, media queries where supported, and fluid/hybrid techniques that degrade gracefully when media queries are unavailable.
Core Concepts
The Email CSS Landscape
| Client | Engine | <style> block | Media queries | Flexbox/Grid | max-width |
|---|---|---|---|---|---|
| Apple Mail | WebKit | Yes | Yes | Yes | Yes |
| iOS Mail | WebKit | Yes | Yes | Yes | Yes |
| Gmail (web) | Custom | Partial (class-based only) | No | No | No |
| Gmail (app) | Custom | Partial | No | No | No |
| Outlook 2019+ | Word | Yes (limited) | No | No | No |
| Outlook.com | Custom | Yes | No | No | Yes |
| Yahoo Mail | Custom | Yes | Yes | No | Yes |
| Thunderbird | Gecko | Yes | Yes | Yes | Yes |
Inline Styles as the Baseline
Because many clients strip or ignore <style> blocks, inline styles are the only reliable way to apply CSS in email:
<td style="padding: 20px; font-size: 16px; line-height: 24px; color: #333333; font-family: Helvetica, Arial, sans-serif;">
Content here
</td>
Table-Based Layout
Tables remain the only reliable cross-client layout mechanism:
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="max-width: 600px; margin: 0 auto;">
<tr>
<td style="padding: 20px;">
Content
</td>
</tr>
</table>
Always set role="presentation" on layout tables so screen readers do not announce them as data tables.
Implementation Patterns
Fluid Hybrid Method (Without Media Queries)
This technique uses max-width, min-width, and the calc() trick to create responsive columns that work without media queries. It degrades well in Gmail:
<!--[if mso]>
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="600">
<tr><td>
<![endif]-->
<div style="max-width: 600px; margin: 0 auto;">
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td style="padding: 10px;">
<!--[if mso]>
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td valign="top" width="290">
<![endif]-->
<div style="display: inline-block; width: 100%; max-width: 290px; vertical-align: top;">
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td style="padding: 10px;">
<p style="margin: 0; font-size: 16px;">Left column content</p>
</td>
</tr>
</table>
</div>
<!--[if mso]>
</td>
<td valign="top" width="290">
<![endif]-->
<div style="display: inline-block; width: 100%; max-width: 290px; vertical-align: top;">
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td style="padding: 10px;">
<p style="margin: 0; font-size: 16px;">Right column content</p>
</td>
</tr>
</table>
</div>
<!--[if mso]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</table>
</div>
<!--[if mso]>
</td></tr></table>
<![endif]-->
Media Query Enhancement
For clients that support <style> blocks with media queries, add progressive enhancement:
<style type="text/css">
/* Reset for clients that support <style> */
body, table, td, p, a, li {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
table, td {
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
}
img {
-ms-interpolation-mode: bicubic;
border: 0;
outline: none;
text-decoration: none;
}
@media only screen and (max-width: 600px) {
.email-container {
width: 100% !important;
max-width: 100% !important;
}
.fluid-column {
width: 100% !important;
max-width: 100% !important;
display: block !important;
}
.stack-column {
display: block !important;
width: 100% !important;
padding-bottom: 16px !important;
}
.mobile-padding {
padding-left: 16px !important;
padding-right: 16px !important;
}
.mobile-center {
text-align: center !important;
}
.mobile-hide {
display: none !important;
mso-hide: all !important;
}
.mobile-full-width-image img {
width: 100% !important;
height: auto !important;
}
}
</style>
Responsive Images
<!-- Fluid image that scales down -->
<img
src="https://example.com/hero.jpg"
alt="Hero banner"
width="600"
style="display: block; width: 100%; max-width: 600px; height: auto; border: 0;"
/>
For retina displays, supply a 2x image and constrain with width:
<img
src="https://example.com/hero@2x.jpg"
alt="Hero banner"
width="600"
style="display: block; width: 100%; max-width: 600px; height: auto;"
/>
Responsive Buttons
Bulletproof buttons that work across clients:
<!-- VML-based button for Outlook + CSS button for others -->
<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="margin: 0 auto;">
<tr>
<td style="border-radius: 4px; background-color: #5469d4; text-align: center;">
<!--[if mso]>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:w="urn:schemas-microsoft-com:office:word"
href="https://example.com"
style="height:48px;v-text-anchor:middle;width:200px;"
arcsize="8%"
strokecolor="#5469d4"
fillcolor="#5469d4">
<w:anchorlock/>
<center style="color:#ffffff;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:bold;">
Click Here
</center>
</v:roundrect>
<![endif]-->
<!--[if !mso]><!-->
<a href="https://example.com"
style="display: inline-block; padding: 14px 32px; background-color: #5469d4; color: #ffffff; font-family: Helvetica, Arial, sans-serif; font-size: 16px; font-weight: bold; text-decoration: none; border-radius: 4px;">
Click Here
</a>
<!--<![endif]-->
</td>
</tr>
</table>
Outlook Conditional Comments
Outlook desktop uses Word for rendering and ignores most CSS. Use conditional comments to provide Outlook-specific markup:
<!--[if mso]>
<table role="presentation" width="600" cellpadding="0" cellspacing="0">
<tr><td>
<![endif]-->
<!-- Standard content here -->
<!--[if mso]>
</td></tr>
</table>
<![endif]-->
Ghost Tables for Outlook Column Layout
<!--[if mso]>
<table role="presentation" width="600"><tr>
<td width="300" valign="top">
<![endif]-->
<div class="stack-column" style="display:inline-block; width:100%; max-width:300px; vertical-align:top;">
<!-- Column 1 -->
</div>
<!--[if mso]>
</td>
<td width="300" valign="top">
<![endif]-->
<div class="stack-column" style="display:inline-block; width:100%; max-width:300px; vertical-align:top;">
<!-- Column 2 -->
</div>
<!--[if mso]>
</td>
</tr></table>
<![endif]-->
Best Practices
- Start with a mobile-first single-column layout and progressively enhance to multi-column for wider viewports.
- Use
role="presentation"on every layout table so assistive technology skips the table semantics. - Set a
max-width: 600pxon the outer container. This is the de facto standard maximum width for email. - Always inline critical styles. Use a build tool (like
juiceor a framework's built-in inliner) to automate this. - Use
display: blockon images to eliminate the phantom gap that appears below images in some clients. - Specify both
widthattribute andstyle="width:..."on images because Outlook reads the HTML attribute while other clients use CSS. - Set
border-collapse: collapseon tables to prevent unwanted spacing between cells. - Use web-safe font stacks:
font-family: Helvetica, Arial, sans-serif. Web fonts load in Apple Mail and some others but fail silently elsewhere. - Always provide
alttext on images. Many corporate clients block images by default. - Test with real clients. No amount of careful coding substitutes for rendering tests in Outlook, Gmail, and Apple Mail.
Common Pitfalls
- Using
marginfor spacing: Outlook ignoresmarginon many elements. Usepaddingon<td>elements or spacer cells instead. - Percentage heights: Email clients inconsistently support percentage-based heights. Use fixed pixel heights or let content define height naturally.
- CSS shorthand in Outlook: Outlook can misinterpret shorthand like
padding: 10px 20px. Prefer longhand:padding-top: 10px; padding-right: 20px; padding-bottom: 10px; padding-left: 20px;. - Forgetting
cellpadding="0" cellspacing="0": Without these attributes, tables inherit browser/client default spacing. - Using
<div>for structure: Divs are unreliable in Outlook. The core structure must be tables. Use divs only within table cells for non-structural purposes. - Background images without VML fallback: CSS
background-imagedoes not work in Outlook desktop. Use VML markup for Outlook and CSS for everything else. - Gmail stripping class-based styles: Gmail supports
<style>blocks but only class selectors — no element selectors, no attribute selectors, no pseudo-classes. Rename classes to avoid conflicts with Gmail's own CSS.
Anti-Patterns
Over-engineering for hypothetical scale. Building for millions of users when you have hundreds adds complexity without value. Solve today's problems first.
Ignoring the existing ecosystem. Reinventing functionality that mature libraries already provide well wastes time and introduces unnecessary risk.
Premature abstraction. Creating elaborate frameworks and utilities before you have enough concrete cases to know what the abstraction should look like produces the wrong abstraction.
Neglecting error handling at boundaries. Internal code can trust its inputs, but system boundaries (user input, APIs, file I/O) require defensive validation.
Skipping documentation for obvious code. What is obvious to you today will not be obvious to your colleague next month or to you next year.
Install this skill directly: skilldb add email-template-skills
Related Skills
Dark Mode Email
Dark mode support patterns for email templates across major email clients
Email Accessibility
Accessible email design patterns for inclusive, standards-compliant email templates
Email Deliverability
Email deliverability essentials including SPF, DKIM, DMARC, and inbox placement
Email Testing
Email testing workflows using Litmus, Email on Acid, Mailtrap, and other QA tools
Mjml
Building responsive email templates with the MJML markup language and toolchain
React Email
Building email templates with React Email components and rendering pipeline