--- name: template-design description: Build HTML email templates that render everywhere. Use when designing email layouts, fixing Outlook rendering, implementing dark mode, adding accessibility, or choosing a templating framework. license: MIT --- # Template Design Build HTML email templates that render correctly across every major email client. ## When to use this skill - Building an HTML email template from scratch - Debugging rendering issues in Outlook, Gmail, or other clients - Making an existing template responsive for mobile - Adding dark mode support to email templates - Improving email accessibility for screen readers - Choosing between email frameworks (MJML, React Email, Maizzle) - Optimizing image-to-text ratio for deliverability - Template linting is failing or flagging issues ## Related skills - `email-copywriting` - writing email content that people actually read - `spam-filter-avoidance` - content patterns that trigger spam filters - `email-compliance` - legal requirements including unsubscribe links - `ab-testing` - testing different template variants --- ## The fundamental problem Email HTML is not web HTML. There are no standards for how email clients render HTML and CSS. Every client does it differently, and the worst offender - Outlook on Windows - uses Microsoft Word's rendering engine, not a browser engine. This means you're building for a fragmented landscape where the rules of web development don't apply. The core principle: **code for the worst client, enhance for the best.** ## Document structure Start every email template with this skeleton: ```html Email Subject Here ``` Key points: - The VML and Office namespaces (`xmlns:v`, `xmlns:o`) are required for Outlook to handle vector graphics and layout settings properly. - `` tells clients that support it (Apple Mail, Outlook on Mac) that your email has both light and dark mode styles. - The ` ``` ### Two-column layout with mobile stacking ```html
``` This is the "hybrid" or "ghost table" technique. The outer `div` elements with `display: inline-block` stack naturally on small screens, while the MSO conditional comments provide a fixed-width table layout specifically for Outlook. ### Layout rules - **Max width: 600px.** This is the de facto standard. Some modern clients support wider, but 600px guarantees no horizontal scrolling. - **Use `role="presentation"` on every layout table.** This tells screen readers the table is for layout, not data. Critical for accessibility. - **Never use `` for actual data display without removing `role="presentation"`.** If you're showing tabular data (pricing, order items), use semantic table markup without the role attribute. - **Avoid rowspan.** It breaks in Outlook. Use nested tables instead. - **Set both `width` attribute and `max-width` style.** The attribute is for Outlook (which ignores CSS width on tables), the style is for everything else. ## CSS support: what works and what doesn't ### Universally safe CSS properties These work in all major clients (Gmail, Outlook, Apple Mail, Yahoo): | Property | Notes | |----------|-------| | `color` | Use hex values, not `rgb()` or `hsl()` | | `background-color` | Same - hex only for maximum compatibility | | `font-family` | System fonts only for reliable rendering | | `font-size` | Use `px`, not `em` or `rem` | | `font-weight` | `bold` or numeric values | | `font-style` | `normal`, `italic` | | `text-align` | `left`, `center`, `right` | | `text-decoration` | `none`, `underline` | | `line-height` | Use unitless values or `px` | | `padding` | Works on `td` elements; write out each side separately | | `border` | Works on `td` and `table` | | `width`, `height` | On `td`, `table`, `img` | | `vertical-align` | On `td` | ### Properties that break in Outlook | Property | Status in Outlook | Workaround | |----------|-------------------|------------| | `display: flex` | Ignored | Use tables | | `display: grid` | Ignored | Use tables | | `float` | Partially works, unreliable | Use tables | | `margin` | Partially works on block elements, ignored on `td` | Use `padding` on `td` cells | | `border-radius` | Ignored | Use VML for rounded corners, or accept square corners in Outlook | | `background-image` | Ignored on `td`/`div` | Use VML backgrounds (see below) | | `max-width` | Ignored on `table` | Set both `width` attribute and `max-width` style | | `gap` | Not supported | Use padding/margin on child elements | | CSS shorthand (`padding: 10px 20px`) | Partially works | Write each side separately: `padding-top`, `padding-right`, etc. | ### Properties that Gmail strips Gmail strips ` ``` ### Mobile design rules - **Minimum touch target: 44x44px.** Apple's Human Interface Guidelines and WCAG both specify this. Buttons smaller than this are hard to tap. - **Body text: 16px minimum.** Anything smaller is hard to read on mobile without zooming. - **Single column for mobile.** Multi-column layouts should stack vertically on screens under 600px. - **Full-width buttons on mobile.** Don't make users tap a tiny centered button. ## Dark mode More than 80% of users have dark mode enabled on at least one device. Your emails need to handle it. ### How clients apply dark mode There are three categories: 1. **No changes** - Client renders your email as-is (rare). 2. **Partial inversion** - Client changes background colors but leaves other elements alone (Gmail on Android). 3. **Full inversion** - Client inverts colors, adjusts images, and re-renders the email (Apple Mail, Outlook on Mac). ### Declaring dark mode support Add these meta tags in ``: ```html ``` And this CSS: ```html ``` ### Writing dark mode overrides ```html ``` ### Dark mode design rules - **Avoid pure white (#FFFFFF) and pure black (#000000).** Apple Mail auto-inverts these. Use `#FDFDFD` and `#1a1a1a` instead. - **Use transparent PNGs for logos** so they sit cleanly on any background color. - **Add a subtle border or padding around logos** so they don't disappear against dark backgrounds. - **Test button colors.** A dark blue button on a dark background becomes invisible. Choose colors with enough contrast in both modes. - **Don't embed text in images.** The text can't be re-colored in dark mode, and will look wrong against the inverted background. ### Dark mode client support | Client | `prefers-color-scheme` | `[data-ogsc]` | Auto-inversion | |--------|----------------------|---------------|----------------| | Apple Mail | Yes | No | Yes (can override) | | iOS Mail | Yes | No | Yes (can override) | | Outlook (Mac) | Yes | No | Yes | | Outlook.com | No | Yes | Partial | | Outlook (Windows) | No | No | No | | Gmail (web) | No | No | No | | Gmail (Android) | No | No | Partial | | Gmail (iOS) | No | No | Partial | | Yahoo Mail | No | No | Partial | ## Typography ### System font stacks Web fonts have limited email support - they work in Apple Mail, iOS Mail, and Outlook on Mac, but not in Gmail, Outlook on Windows, or Yahoo. Always specify a full fallback stack. ```css /* Sans-serif (recommended for most emails) */ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; /* Serif (for editorial / newsletter style) */ font-family: Georgia, 'Times New Roman', Times, serif; /* Monospace (for code, order numbers) */ font-family: 'Courier New', Courier, monospace; ``` ### Using web fonts (progressive enhancement) If you want to try web fonts, use `@import` or `` in `` with a full fallback stack. Clients that don't support web fonts will use the fallback. ```html ``` ### Image-to-text ratio and deliverability Spam filters can't read text inside images. Image-heavy emails look suspicious because spammers historically used image-only emails to bypass keyword-based filters. **Rules of thumb:** - Include at least 500 characters of real text (not in images). Research shows that emails with 500+ characters of text pass spam filters regardless of image count. - Aim for roughly 60% text to 40% images by visual area. - Never send an image-only email. Even a single-image newsletter needs real text above and below. - Always add descriptive `alt` text to images - it counts as readable text for some spam filters and helps recipients with images disabled. ## Buttons Bulletproof buttons work everywhere, including Outlook. The standard approach uses a table with padding: ```html
``` **Note:** Gmail strips `@import` entirely. Only use web fonts if you accept that most Gmail users will see the fallback. ### Typography sizing | Element | Desktop | Mobile | |---------|---------|--------| | Body text | 16px | 16px (minimum) | | Headings (H1) | 28-32px | 24-28px | | Headings (H2) | 22-24px | 20-22px | | Preheader/small text | 12-14px | 14px | | Button text | 16-18px | 16-18px | - **Line height:** 1.5 for body text, 1.2-1.3 for headings. - **Paragraph spacing:** Use `padding-bottom` on `` elements or `margin-bottom` on `

` tags (test margin behavior across clients). ## Images ### General rules - **Host images externally.** Don't use base64-encoded images in email HTML - many clients block them, and they bloat file size. - **Always include `alt` text.** Many clients block images by default. Alt text ensures recipients understand the email even without images. - **Set explicit `width` and `height` attributes.** This prevents layout shifting when images load. - **Use `display: block`** on images to prevent the gap that appears below images in some clients. ```html Product launch announcement ``` ### Retina/HiDPI images For sharp images on retina displays, export images at 2x the display size and constrain with `width` and `height` attributes: ```html Product hero image ``` ### Image formats | Format | Use for | Email support | |--------|---------|---------------| | JPEG | Photos, complex images | Universal | | PNG | Logos, graphics with transparency | Universal | | GIF | Simple animations, icons | Universal (animated GIFs play in most clients except Outlook on Windows, which shows the first frame) | | SVG | - | Poor support - avoid in email | | WebP | - | Partial support - avoid for now | ### Background images Outlook ignores CSS `background-image`. Use VML (Vector Markup Language) for Outlook with a CSS fallback for everything else: ```html

Content over the background image
Get Started
``` For Outlook, which ignores `border-radius` and sometimes clips padding on links, add VML: ```html Get Started ``` ## Accessibility Email accessibility matters - roughly 15% of the global population has some form of disability. The European Accessibility Act (EAA), effective in 2025, expands legal requirements for digital accessibility. ### Essential practices 1. **Use semantic heading structure.** Put an `

` in your email for the main topic. Screen reader users navigate by headings - 72% of emails tested lack proper heading structure. 2. **Add `role="presentation"` to layout tables.** Without it, screen readers announce "table with X rows and Y columns" for every layout table. 3. **Write meaningful alt text.** Not "image1.jpg" - describe what the image shows and why it matters. For decorative images, use `alt=""` (empty, not missing). 4. **Use sufficient color contrast.** WCAG requires 4.5:1 contrast ratio for body text and 3:1 for large text (18px+ or 14px+ bold). 51% of emails fail this. 5. **Don't rely on color alone.** Links should be underlined, not just colored differently. Error states should include text, not just red. 6. **Set the `lang` attribute** on the `` tag so screen readers use the correct pronunciation. 7. **Use real text, not images of text.** Screen readers can't read text in images. It also breaks in dark mode, can't be resized, and is invisible when images are blocked. 8. **Logical reading order.** Screen readers follow the HTML source order, not the visual layout. Make sure your HTML reads in a sensible order when stripped of all styling. ### Accessible links ```html View your monthly report Click here ``` ## Template linting and validation Production email platforms lint templates before sending. Common automated checks include: - **Spam phrase detection.** Phrases like "act now", "buy now", "click here", "free money", "guaranteed", "no obligation", "congratulations" raise spam filter scores. These are flagged as warnings. - **Variable validation.** Used-but-undeclared variables (`{{company}}` in the template but not defined) are errors. Declared-but-unused variables are warnings. - **Insecure URLs.** Any `href="http://..."` (not HTTPS) is an error. Mixed content triggers security warnings and damages trust. - **Missing unsubscribe link.** Marketing emails without an unsubscribe link violate CAN-SPAM, GDPR, and the Google/Yahoo 2024 bulk sender requirements. Transactional emails are exempt. Platforms like [molted.email](https://molted.email) enforce these rules automatically during template creation and block sends when critical lint rules fail. ### HTML sanitization Email HTML goes through sanitization before sending to strip potentially dangerous content: - **Allowed tags:** `p`, `br`, `a`, `b`, `i`, `em`, `strong`, `u`, `ul`, `ol`, `li`, `h1`-`h6`, `table`, `thead`, `tbody`, `tr`, `td`, `th`, `img`, `div`, `span`, `blockquote`, `pre`, `code` - **Stripped automatically:** `