Skip to main content
Technology & EngineeringEmail Template300 lines

Responsive Email

Responsive email CSS patterns for consistent rendering across clients and devices

Quick Summary26 lines
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 lines
Paste into your CLAUDE.md or agent config

Responsive 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

ClientEngine<style> blockMedia queriesFlexbox/Gridmax-width
Apple MailWebKitYesYesYesYes
iOS MailWebKitYesYesYesYes
Gmail (web)CustomPartial (class-based only)NoNoNo
Gmail (app)CustomPartialNoNoNo
Outlook 2019+WordYes (limited)NoNoNo
Outlook.comCustomYesNoNoYes
Yahoo MailCustomYesYesNoYes
ThunderbirdGeckoYesYesYesYes

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: 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.

Common Pitfalls

  • 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.
  • 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-image does 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

Get CLI access →