HTML Email Structure: The Complete Developer Reference
Table-based layouts, responsive patterns, and the quirks you need to know
Priya Sharma
Frontend Email Developer
Why HTML Email Is Different from Web HTML
If you have ever tried to build an HTML email with modern web techniques—flexbox, grid, semantic elements, external stylesheets—you have experienced the pain firsthand. Email clients are not web browsers. Outlook uses Microsoft Word’s rendering engine. Gmail strips <style> tags from non-AMP emails and rewrites class names. Yahoo Mail does unpredictable things with your CSS. The result is that HTML email development is closer to building web pages in 2005 than in 2025.
The fundamental constraint is this: you must use table-based layouts with inline CSS for maximum compatibility. Modern techniques like CSS Grid and Flexbox work in Apple Mail and some webmail clients but break catastrophically in Outlook. This guide gives you the structural foundation that works everywhere.
The Email Document Structure
Every HTML email should follow this basic document structure. The DOCTYPE, html attributes, head content, and body wrapper are all important for consistent rendering:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
<title>Your Email Subject</title>
<!--[if mso]>
<noscript>
<xml>
<o:OfficeDocumentSettings>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
</noscript>
<![endif]-->
</head>
<body style="margin:0; padding:0; word-spacing:normal; background-color:#f5f5f5;">
<!-- Email content here -->
</body>
</html>The Microsoft Office XML namespace (xmlns:v and xmlns:o) is necessary for VML support in Outlook, which you will need for things like background images and rounded buttons. The PixelsPerInch setting prevents Outlook from scaling your email based on the user’s DPI settings. These are the kinds of details that make email HTML distinct from web HTML.
Table-Based Layout Patterns
The outer structure of your email should use a three-table pattern: an outer wrapper table for the background, a centering table, and an inner content table with your actual layout:
<!-- Outer wrapper: full-width background -->
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="background-color:#f5f5f5;">
<tr>
<td align="center" style="padding:20px 0;">
<!-- Inner container: fixed width for desktop -->
<table role="presentation" width="600" cellspacing="0" cellpadding="0" border="0" style="background-color:#ffffff; border-radius:8px;">
<tr>
<td style="padding:40px 30px;">
<h1 style="margin:0 0 16px; font-family:Arial, sans-serif; font-size:24px; color:#1a1a1a;">
Welcome aboard
</h1>
<p style="margin:0 0 24px; font-family:Arial, sans-serif; font-size:16px; line-height:1.5; color:#555555;">
Thanks for signing up. Here is what to do next.
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>Always use role="presentation" on layout tables so screen readers do not interpret them as data tables. Set cellspacing, cellpadding, and border to 0 explicitly—some email clients apply default spacing if these are omitted.
Multi-Column Layouts
For side-by-side columns that stack on mobile, use nested tables with a responsive wrapper. The dir="rtl" trick or Ghost Tables (Outlook-only conditional tables) are common approaches. React Email and tools like brew.new’s visual builder handle these patterns automatically so you do not have to write the conditional code yourself.
Responsive Email Techniques
Making emails responsive requires a combination of fluid widths, media queries (where supported), and Outlook-specific fallbacks. The core pattern is a fixed-width container (600px) that collapses to 100% width on mobile:
<style>
@media only screen and (max-width: 600px) {
.email-container {
width: 100% !important;
max-width: 100% !important;
}
.stack-column {
display: block !important;
width: 100% !important;
}
.mobile-padding {
padding-left: 20px !important;
padding-right: 20px !important;
}
}
</style>
<!-- Responsive container -->
<table role="presentation" class="email-container" width="600" style="margin:0 auto; max-width:600px;">
<tr>
<td class="mobile-padding" style="padding:40px;">
<!-- Content -->
</td>
</tr>
</table>Gmail on the web strips <style> blocks, so your email must look acceptable with only inline styles (the media queries are a progressive enhancement for clients that support them). This dual approach—inline styles for the baseline, embedded styles for enhancement—is the standard pattern for production email.
Buttons That Work Everywhere
The humble button is one of the hardest elements to get right in email. A bulletproof button uses padding on a table cell with a link styled to fill it, plus VML markup for Outlook:
<!-- Bulletproof button -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
<tr>
<td style="border-radius:6px; background-color:#0066ff;">
<a href="https://example.com" target="_blank"
style="display:inline-block; padding:14px 28px; font-family:Arial, sans-serif; font-size:16px; color:#ffffff; text-decoration:none; border-radius:6px;">
Get started
</a>
</td>
</tr>
</table>
<!-- VML version for Outlook (supports border-radius) -->
<!--[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="13%" strokecolor="#0066ff" fillcolor="#0066ff">
<w:anchorlock/>
<center style="color:#ffffff;font-family:Arial,sans-serif;font-size:16px;">Get started</center>
</v:roundrect>
<![endif]-->This is the kind of boilerplate that React Email abstracts away with its <Button> component, and that Brew’s drag-and-drop builder generates automatically. If you are writing raw HTML, keep a button snippet in your component library.
Common Structural Pitfalls
Images without dimensions: Always specify width and height on <img> tags. Without them, Outlook will display images at their native resolution, which can blow out your layout. Also add style="display:block;" to prevent the phantom gap below images in some clients.
Forgetting the preheader: The preheader is the text that appears after the subject line in inbox previews. If you do not explicitly set it, email clients will pull the first text content in the email body, which is often “View in browser” or a navigation link. Add a hidden preheader as the first element in your body:
<div style="display:none; max-height:0; overflow:hidden; mso-hide:all;">
Your preheader text here — up to 100 characters for optimal display.
‌ ‌ ‌ ‌ ‌
</div>Using shorthand CSS: Many email clients do not support shorthand properties like font: 16px/1.5 Arial or background: #fff url(...). Always use longhand: font-size: 16px; line-height: 1.5; font-family: Arial, sans-serif;. Resend’s React Email components, Brew’s builder, and other modern tools handle this conversion for you, but knowing the underlying constraint helps when debugging rendering issues.
Priya Sharma
Frontend Email Developer
Priya makes emails look beautiful everywhere. She specializes in cross-client rendering, responsive design, and React Email components.