KAHIBARO
Discord Login Register

18.4. HTML Emails

Why HTML Emails Matter

Plain text emails are simple and reliable, but many real applications need richer messages. Think of:

All of these are HTML emails. They are small web pages, but with very strict rules.

In this chapter you will not learn how to send emails. You will focus on how to build HTML email content that works in real inboxes.

Key idea: HTML emails are like tiny web pages, but email clients support old and limited HTML and CSS. You must code them in a careful, old‑school way.


HTML vs Plain Text Emails

Plain Text Emails

A plain text email contains only characters, no formatting:

text
Hi Alice,
Your order has been shipped!
Track it here:
https://example.com/track/123
Thanks,
Example Store

Pros:

Cons:

HTML Emails

HTML emails support formatting and structure:

html
<html>
  <body>
    <p>Hi Alice,</p>
    <p><strong>Your order has been shipped!</strong></p>
    <p>
      Track it here:
      <a href="https://example.com/track/123">View tracking status</a>
    </p>
    <p>Thanks,<br>Example Store</p>
  </body>
</html>

Pros:

Cons:

In practice, many applications send multipart emails with both versions:

The email client chooses which one to show.

Rule: Always provide a plain text fallback when sending HTML emails. This improves deliverability and accessibility.


Core Structure of an HTML Email

Basic HTML Skeleton

Email HTML usually looks like this:

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Your subject here</title>
  </head>
  <body>
    <!-- Content -->
  </body>
</html>

Some clients ignore <head> contents, but including it is still good practice.

Use Tables for Layout

Modern web pages often use flexbox or CSS grid. Email clients, especially Outlook, often do not support them well. For layout you usually use <table> tags.

Example: a simple one‑column email layout:

html
<body style="margin:0; padding:0;">
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0">
    <tr>
      <td align="center" style="padding:20px 0;">
        <!-- Container -->
        <table role="presentation" width="600" cellpadding="0" cellspacing="0" border="0" style="border:1px solid #dddddd;">
          <tr>
            <td style="padding:20px; font-family:Arial, sans-serif; font-size:16px; line-height:1.5;">
              <!-- Email content here -->
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</body>

Notes:

Rule: Use <table> based layouts for HTML emails, not flexbox or CSS grid. This is crucial for compatibility.


Styling HTML Emails Safely

Inline Styles

Many email clients strip out <style> blocks or ignore some CSS sources. The most reliable way to apply styles is with the style attribute.

Bad (may be ignored):

html
<head>
  <style>
    .button {
      background: #4CAF50;
    }
  </style>
</head>
<body>
  <a href="..." class="button">Click</a>
</body>

Better:

html
<a href="https://example.com" 
   style="background:#4CAF50; color:#ffffff; padding:10px 20px; text-decoration:none; border-radius:4px; display:inline-block;">
  Click
</a>

This is verbose, but works across more clients.

Commonly Supported CSS Properties

Safe to use in most clients:

CategoryExamples
Textfont-family, font-size, font-weight, color, line-height
Box modelpadding, margin (limited), border, background-color
Display/layoutdisplay:block, display:inline-block, text-align, vertical-align
Imageswidth, height, border-radius (partially)

Risky or often unsupported:

FeatureNotes
FlexboxPoor support, especially in Outlook
CSS GridPoor support
positionOften ignored
Web fontsLimited support, require fallbacks
Complex media queriesNot supported in many desktop clients

When unsure, test or check email CSS support tables (for example, caniemail.com).

Use System Fonts

Web fonts are not guaranteed to load. Use a stack of safe fonts:

html
<span style="font-family: Arial, Helvetica, sans-serif; font-size:16px;">
  Hello from our app!
</span>

Creating a Simple HTML Template

Here is a very small but realistic HTML email for a password reset.

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Password reset</title>
  </head>
  <body style="margin:0; padding:0; background-color:#f4f4f4;">
    <table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0">
      <tr>
        <td align="center" style="padding:20px 0;">
          <table role="presentation" width="600" cellpadding="0" cellspacing="0" border="0" style="background-color:#ffffff; border-radius:4px; overflow:hidden;">
            <!-- Header -->
            <tr>
              <td style="background-color:#2b6cb0; padding:16px 24px; color:#ffffff; font-family:Arial, sans-serif; font-size:20px;">
                Example App
              </td>
            </tr>
            <!-- Body -->
            <tr>
              <td style="padding:24px; font-family:Arial, sans-serif; font-size:16px; color:#333333; line-height:1.5;">
                <p style="margin:0 0 16px 0;">Hi {{ user_name }},</p>
                <p style="margin:0 0 16px 0;">
                  We received a request to reset your password. Click the button below to choose a new one.
                </p>
                <p style="margin:0 0 24px 0; text-align:center;">
                  <a href="{{ reset_link }}"
                     style="background-color:#2b6cb0; color:#ffffff; text-decoration:none; padding:12px 24px; border-radius:4px; display:inline-block; font-weight:bold;">
                    Reset your password
                  </a>
                </p>
                <p style="margin:0 0 16px 0; font-size:14px; color:#666666;">
                  If you did not request a password reset, you can ignore this email.
                </p>
                <p style="margin:0; font-size:14px; color:#666666;">
                  Thanks,<br>Example App Team
                </p>
              </td>
            </tr>
            <!-- Footer -->
            <tr>
              <td style="background-color:#f4f4f4; padding:12px 24px; text-align:center; font-family:Arial, sans-serif; font-size:12px; color:#999999;">
                © {{ year }} Example App. All rights reserved.
              </td>
            </tr>
          </table>
        </td>
      </tr>
    </table>
  </body>
</html>

Dynamic parts, like {{ user_name }}, {{ reset_link }} and {{ year }}, will be filled by your backend template system.


Buttons and Call‑To‑Action Links

Button as a Styled Link

Most email buttons are just <a> tags with styles:

html
<a href="{{ verify_link }}"
   style="background-color:#38a169; color:#ffffff; text-decoration:none; padding:12px 30px; border-radius:4px; display:inline-block; font-family:Arial, sans-serif; font-size:16px;">
  Verify your email
</a>

You can center it using a containing <p> with text-align:center.

Bulletproof Buttons with Tables

Some clients handle inline styles inconsistently on <a>. You can use a button built from a table cell.

html
<table role="presentation" cellpadding="0" cellspacing="0" border="0" align="center">
  <tr>
    <td bgcolor="#3182ce" style="border-radius:4px;">
      <a href="{{ action_link }}"
         style="display:inline-block; padding:12px 24px; font-family:Arial, sans-serif; font-size:16px; color:#ffffff; text-decoration:none;">
        Confirm your account
      </a>
    </td>
  </tr>
</table>

This is more verbose, but tends to be more reliable.


Using Images in HTML Emails

Inline Images vs External URLs

Most of the time you will host images on a server and reference them with src URLs:

html
<img src="https://cdn.example.com/email/logo.png"
     alt="Example App logo"
     width="120"
     style="display:block; margin:0 auto 16px auto;">

Important points:

Avoid Background Images

Background images in CSS are often not supported. Prefer regular <img> elements.

Bad:

html
<td style="background-image:url('https://...');">
  ...
</td>

Better: just use an <img> tag at the top of a cell.

Logo Example

A header with a logo:

html
<tr>
  <td style="padding:20px; text-align:center; background-color:#1a202c;">
    <img src="https://cdn.example.com/logo-email.png"
         alt="Example App"
         width="140"
         style="display:block; margin:0 auto;">
  </td>
</tr>

Making HTML Emails Responsive

Many recipients read emails on phones. A 600‑pixel fixed width layout is standard, but on small screens you want text to remain readable.

Full responsive design can be complex in emails and heavy use of media queries may not work everywhere. For beginners, focus on:

Simple example with a safe width:

html
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0">
  <tr>
    <td align="center">
      <table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="max-width:600px;">
        <tr>
          <td style="padding:16px; font-family:Arial, sans-serif; font-size:16px;">
            Content
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>

Here max-width:600px lets the email shrink nicely on narrow screens.

Rule: Prefer simple, single column layouts with large fonts and clear buttons. Complex multi‑column responsive layouts are hard to make reliable in emails.


Dynamic Content and Templating

In a backend application you will rarely write raw HTML with actual values. Instead, you create a template with placeholders.

Example for a “welcome” email template, using a generic template syntax:

html
<p style="font-family:Arial, sans-serif; font-size:16px;">
  Hi {{ user_name }},
</p>
<p style="font-family:Arial, sans-serif; font-size:16px;">
  Welcome to Example App! Click the button below to get started.
</p>
<p style="text-align:center;">
  <a href="{{ onboarding_link }}"
     style="background-color:#2b6cb0; color:#ffffff; text-decoration:none; padding:12px 24px; border-radius:4px; display:inline-block;">
    Go to your dashboard
  </a>
</p>

Your backend language and template engine will:

  1. Load this HTML file as a template.
  2. Replace {{ user_name }} and {{ onboarding_link }} with real values.
  3. Send the final HTML string through your email sending code.

Accessibility and Text‑Only Fallbacks

HTML emails should still be readable if:

A few practices help:

Plain text version example for the earlier password reset email:

text
Hi {{ user_name }},
We received a request to reset your password.
Reset your password by opening this link:
{{ reset_link }}
If you did not request a password reset, you can ignore this email.
Thanks,
Example App Team

Common Pitfalls and Gotchas

Here are typical mistakes when creating HTML emails:

MistakeProblem
Using modern CSS layout onlyLayout breaks in Outlook and older clients
Putting all styles in <style> onlyStyles may be stripped or ignored
No plain text versionWorse deliverability and bad experience in some clients
Relying only on images for contentContent invisible when images are blocked
Very wide content (full‑width 1200px)Hard to read on mobile, horizontal scrolling
Forgetting alt attributesScreen readers and blocked images show nothing useful
Using JavaScriptJavaScript is usually removed and is also a security risk

Rule: Do not use JavaScript in HTML emails. It is stripped or blocked by almost all email clients.


Reusable Patterns for Application Emails

You can design basic patterns and reuse them across many emails.

Common Layout Blocks

  1. Header
    Contains logo and maybe application name.
  2. Body
    • Greeting: “Hi {{ user_name }},”
    • Main message paragraph
    • Call‑to‑action button
    • Additional information or instructions
  3. Footer
    • Copyright info
    • Company address (for legal reasons in many countries)
    • “You received this email because …” text

Example footer:

html
<p style="margin:0; font-family:Arial, sans-serif; font-size:12px; color:#999999; text-align:center;">
  You received this email because you signed up for Example App.
</p>
<p style="margin:4px 0 0 0; font-family:Arial, sans-serif; font-size:12px; color:#999999; text-align:center;">
  © {{ year }} Example App, Inc. 123 Example Street, Example City
</p>

You can extract these repeated sections into separate templates in your backend, and include them in each email template.


Summary

HTML emails are constrained mini web pages that must:

With these patterns, your backend can generate HTML emails for verification, password resets, order receipts, and many other common flows.

Views: 6

Comments

Please login to add a comment.

Don't have an account? Register now!