· Email

HTML Email Best Practices

Master the art of creating HTML emails that work everywhere.

HTML emails are notoriously tricky. What works perfectly in Gmail might break in Outlook. What looks great on mobile might be unreadable on desktop. Email clients have wildly different rendering engines, limited CSS support, and unpredictable behavior. In this guide, you’ll learn battle-tested techniques for creating HTML emails that work reliably across all major email clients and devices.

Building HTML emails requires a different mindset than building websites—think tables, inline styles, and defensive coding.

The Email HTML Landscape

Email clients use different rendering engines:

  • Gmail - Custom engine with limited CSS
  • Outlook (Windows) - Microsoft Word rendering engine
  • Apple Mail - WebKit (Safari engine)
  • Outlook.com - Modern web standards
  • Yahoo Mail - Custom engine
  • Mobile clients - Various (iOS Mail, Gmail app, etc.)

This fragmentation means you can’t use modern CSS features you’d use on websites.

Basic Email HTML Structure

Start with this foundation:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Email Subject</title>
  <style>
    /* CSS goes here */
  </style>
</head>
<body style="margin: 0; padding: 0; font-family: Arial, sans-serif;">
  <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
    <tr>
      <td style="padding: 20px 0;">
        <!-- Email content goes here -->
      </td>
    </tr>
  </table>
</body>
</html>

Use Tables for Layout

Yes, really. Tables are the most reliable way to create email layouts:

<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="600" style="margin: 0 auto;">
  <!-- Header -->
  <tr>
    <td style="background: #0066cc; padding: 20px; text-align: center;">
      <h1 style="color: white; margin: 0;">Company Name</h1>
    </td>
  </tr>
  
  <!-- Content -->
  <tr>
    <td style="padding: 40px 30px; background: #ffffff;">
      <h2 style="margin: 0 0 20px 0;">Email Heading</h2>
      <p style="margin: 0 0 15px 0; line-height: 1.5;">
        Email content goes here...
      </p>
    </td>
  </tr>
  
  <!-- Footer -->
  <tr>
    <td style="background: #f4f4f4; padding: 20px; text-align: center; font-size: 12px; color: #666;">
      © 2024 Company Name. All rights reserved.
    </td>
  </tr>
</table>

Important attributes:

  • role="presentation" - Tells screen readers this is layout, not data
  • cellspacing="0" - Removes space between cells
  • cellpadding="0" - Removes padding in cells
  • border="0" - Removes table borders

Inline CSS is Essential

Most email clients strip <style> tags. Use inline styles:

<!-- ❌ Bad: External styles won't work -->
<p class="text">Hello</p>

<!-- ✅ Good: Inline styles -->
<p style="color: #333; font-size: 16px; line-height: 1.5; margin: 0 0 15px 0;">
  Hello
</p>

You can use <style> tags for media queries, but always include inline styles as fallback.

Responsive Email Design

Use media queries for mobile optimization:

<style>
  /* Desktop styles (inline styles are mobile-first) */
  @media only screen and (min-width: 600px) {
    .container {
      width: 600px !important;
    }
    .column {
      width: 50% !important;
    }
  }
</style>

<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" class="container">
  <tr>
    <td class="column" style="display: inline-block; width: 100%; vertical-align: top;">
      Column 1
    </td>
    <td class="column" style="display: inline-block; width: 100%; vertical-align: top;">
      Column 2
    </td>
  </tr>
</table>

Images in Email

Always Include Alt Text

<img 
  src="https://example.com/logo.png" 
  alt="Company Logo"
  width="200"
  height="50"
  style="display: block; border: 0;"
>

Key Image Attributes

  • width and height - Prevent layout shifts
  • alt - Shows when images are blocked
  • style="display: block;" - Removes gap below image
  • border="0" - Removes border in Outlook

Host Images Externally

<!-- ✅ Good: Full URL -->
<img src="https://cdn.example.com/email-header.jpg" alt="Header">

<!-- ❌ Bad: Relative path -->
<img src="/images/header.jpg" alt="Header">

<!-- ❌ Bad: Embedded (increases email size) -->
<img src="data:image/png;base64,..." alt="Header">

Buttons That Work

Table-based Button

The most reliable button approach:

<table role="presentation" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td style="border-radius: 4px; background: #0066cc;">
      <a 
        href="https://example.com/action" 
        style="display: inline-block; padding: 12px 24px; font-family: Arial, sans-serif; font-size: 16px; color: #ffffff; text-decoration: none; border-radius: 4px;">
        Click Here
      </a>
    </td>
  </tr>
</table>

Bulletproof Button (VML for Outlook)

<!--[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:40px;v-text-anchor:middle;width:200px;" arcsize="10%" stroke="f" fillcolor="#0066cc">
  <w:anchorlock/>
  <center style="color:#ffffff;font-family:Arial,sans-serif;font-size:16px;">
    Click Here
  </center>
</v:roundrect>
<![endif]-->
<!--[if !mso]><!-->
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td style="border-radius: 4px; background: #0066cc;">
      <a href="https://example.com" style="display: inline-block; padding: 12px 24px; color: #ffffff; text-decoration: none;">
        Click Here
      </a>
    </td>
  </tr>
</table>
<!--<![endif]-->

Text Formatting

Safe Font Stack

<p style="font-family: Arial, Helvetica, sans-serif; font-size: 16px; line-height: 1.5; color: #333333;">
  Your text here
</p>

Safe fonts:

  • Arial
  • Helvetica
  • Georgia
  • Times New Roman
  • Courier New
  • Verdana

Spacing and Margins

<!-- Use padding and margin inline -->
<p style="margin: 0 0 15px 0; padding: 0;">Paragraph</p>

<!-- Add spacing with empty cells -->
<tr>
  <td style="height: 20px; font-size: 0; line-height: 0;">&nbsp;</td>
</tr>

Dark Mode Support

Optimize for dark mode:

<style>
  @media (prefers-color-scheme: dark) {
    .bg-white { background-color: #000000 !important; }
    .text-dark { color: #ffffff !important; }
  }
</style>

<table role="presentation" width="600" class="bg-white">
  <tr>
    <td style="padding: 20px;">
      <p class="text-dark" style="color: #333333;">
        This text adapts to dark mode
      </p>
    </td>
  </tr>
</table>

Complete Email Template

Here’s a production-ready template:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Newsletter</title>
  <style>
    body { margin: 0; padding: 0; }
    table { border-collapse: collapse; }
    img { border: 0; display: block; }
    
    @media only screen and (max-width: 600px) {
      .container { width: 100% !important; }
      .mobile-padding { padding: 10px !important; }
    }
  </style>
</head>
<body style="margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;">
  <!-- Wrapper -->
  <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background-color: #f4f4f4;">
    <tr>
      <td style="padding: 20px 0;">
        
        <!-- Email Container -->
        <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="600" class="container" style="margin: 0 auto; background-color: #ffffff;">
          
          <!-- Header -->
          <tr>
            <td style="background-color: #0066cc; padding: 30px; text-align: center;">
              <img 
                src="https://example.com/logo.png" 
                alt="Company Logo"
                width="150"
                height="40"
                style="display: block; margin: 0 auto;"
              >
            </td>
          </tr>
          
          <!-- Hero Image -->
          <tr>
            <td>
              <img 
                src="https://example.com/hero.jpg" 
                alt="Hero Image"
                width="600"
                height="300"
                style="width: 100%; height: auto; display: block;"
              >
            </td>
          </tr>
          
          <!-- Content -->
          <tr>
            <td class="mobile-padding" style="padding: 40px 30px;">
              <h1 style="margin: 0 0 20px 0; font-size: 28px; line-height: 1.3; color: #333333;">
                Welcome to Our Newsletter
              </h1>
              
              <p style="margin: 0 0 15px 0; font-size: 16px; line-height: 1.5; color: #666666;">
                Thank you for subscribing! We're excited to share our latest updates with you.
              </p>
              
              <p style="margin: 0 0 25px 0; font-size: 16px; line-height: 1.5; color: #666666;">
                Here's what you can expect from us...
              </p>
              
              <!-- Button -->
              <table role="presentation" cellspacing="0" cellpadding="0" border="0">
                <tr>
                  <td style="border-radius: 4px; background-color: #0066cc;">
                    <a 
                      href="https://example.com/subscribe" 
                      style="display: inline-block; padding: 14px 28px; font-family: Arial, sans-serif; font-size: 16px; color: #ffffff; text-decoration: none; border-radius: 4px; font-weight: bold;">
                      Get Started
                    </a>
                  </td>
                </tr>
              </table>
            </td>
          </tr>
          
          <!-- Divider -->
          <tr>
            <td style="padding: 0 30px;">
              <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
                <tr>
                  <td style="border-top: 1px solid #e0e0e0;"></td>
                </tr>
              </table>
            </td>
          </tr>
          
          <!-- Footer -->
          <tr>
            <td style="padding: 30px; text-align: center; background-color: #f9f9f9;">
              <p style="margin: 0 0 10px 0; font-size: 12px; line-height: 1.5; color: #999999;">
                © 2024 Company Name. All rights reserved.
              </p>
              <p style="margin: 0; font-size: 12px; line-height: 1.5; color: #999999;">
                123 Street Name, City, State 12345
              </p>
              <p style="margin: 10px 0 0 0; font-size: 12px; line-height: 1.5;">
                <a href="https://example.com/unsubscribe" style="color: #0066cc; text-decoration: underline;">
                  Unsubscribe
                </a>
              </p>
            </td>
          </tr>
          
        </table>
        <!-- End Email Container -->
        
      </td>
    </tr>
  </table>
  <!-- End Wrapper -->
</body>
</html>

Testing Your Emails

Test Across Clients

  • Gmail (web, iOS, Android)
  • Outlook (Windows, Mac, web)
  • Apple Mail (Mac, iOS)
  • Yahoo Mail
  • Outlook.com

Tools

  • Litmus - Comprehensive testing platform
  • Email on Acid - Cross-client testing
  • Mail Tester - Spam score and rendering
  • Putsmail - Send test emails

Manual Testing Checklist

  • ✅ Images load correctly
  • ✅ Links work
  • ✅ Buttons are clickable
  • ✅ Text is readable
  • ✅ Layout doesn’t break
  • ✅ Renders on mobile
  • ✅ Works with images disabled
  • ✅ Passes spam filters

Best Practices

Keep width under 600px - Most email clients limit width ✅ Use inline CSS - External styles are stripped ✅ Include alt text - Images are often blocked ✅ Test extensively - Email clients vary wildly ✅ Provide plain text version - Some users prefer it ✅ Include unsubscribe link - Required by law ✅ Use web-safe fonts - Custom fonts don’t work everywhere ✅ Avoid background images - Unreliable support

Common Mistakes

Using div-based layouts - Tables are more reliable ❌ External CSS files - Won’t load ❌ JavaScript - Completely blocked ❌ Forms - Don’t work in email ❌ Video embeds - Link to video instead ❌ Complex CSS - Flexbox, Grid don’t work ❌ Assuming modern features - Stick to basics

Accessibility

  • Use semantic HTML where possible
  • Include descriptive alt text
  • Ensure good color contrast
  • Use readable font sizes (14px minimum)
  • Make clickable areas large enough
  • Provide plain text alternative
  • Test with screen readers

Include These Elements

  • Physical mailing address
  • Clear unsubscribe link
  • Accurate “From” name
  • Honest subject line
  • Company identification

Privacy Compliance

  • GDPR (Europe)
  • CAN-SPAM (USA)
  • CASL (Canada)
  • Get explicit consent
  • Honor opt-outs immediately

Keep Learning

Try building email templates in the htmlEditor.net playground today!

HTML email is challenging, but with the right techniques and thorough testing, you can create beautiful emails that work everywhere. Start simple, test often, and always think about the constraints of email clients.

← Back to all blog posts

    Share: