HTML emails are a dark art, and the most surprising thing is how much they don’t follow the web’s HTML/CSS rules.
Let’s look at a simple example. Imagine you want a two-column layout with a heading above it. On the web, you’d use divs and CSS display: flex or float. For email, that’s a recipe for disaster. Instead, you use tables.
<!DOCTYPE html>
<html>
<head>
<title>Email Layout Example</title>
<style type="text/css">
.container {
width: 600px;
margin: 0 auto;
background-color: #f0f0f0;
padding: 20px;
}
.column {
width: 48%; /* Slightly less than 50% to account for spacing */
float: left; /* This is a fallback, tables are better */
padding: 10px;
box-sizing: border-box;
}
.header {
text-align: center;
padding-bottom: 20px;
}
img {
max-width: 100%;
height: auto;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Welcome to Our Newsletter!</h1>
</div>
<div class="column">
<p>This is the content for the first column. It needs to be responsive and look good on various email clients.</p>
<img src="placeholder.jpg" alt="Placeholder Image">
</div>
<div class="column">
<p>This is the content for the second column. We're using tables for robust layout control.</p>
<img src="placeholder.jpg" alt="Placeholder Image">
</div>
</div>
</body>
</html>
If you send this to Gmail, it might look okay. Outlook? Probably a mess. Apple Mail? Who knows. The divs and floats are too unpredictable.
Here’s how you’d build that same layout reliably using tables:
<!DOCTYPE html>
<html>
<head>
<title>Email Layout Example (Tables)</title>
<style type="text/css">
body { margin: 0; padding: 0; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
table { border-spacing: 0; border-collapse: collapse; }
td { padding: 0; }
img { border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; }
.wrapper { width: 100%; table-layout: fixed; background-color: #f0f0f0; }
.main { width: 600px; margin: 0 auto; border-spacing: 0; border-collapse: collapse; }
.header { text-align: center; padding: 20px; }
.column { width: 50%; vertical-align: top; padding: 10px; }
</style>
</head>
<body>
<center class="wrapper">
<table class="main" width="600">
<tr>
<td class="header">
<h1>Welcome to Our Newsletter!</h1>
</td>
</tr>
<tr>
<td>
<table width="100%">
<tr>
<td class="column">
<p>This is the content for the first column. It needs to be responsive and look good on various email clients.</p>
<img src="placeholder.jpg" alt="Placeholder Image" width="100%">
</td>
<td class="column">
<p>This is the content for the second column. We're using tables for robust layout control.</p>
<img src="placeholder.jpg" alt="Placeholder Image" width="100%">
</td>
</tr>
</table>
</td>
</tr>
</table>
</center>
</body>
</html>
Notice the center tag and the nested tables. The outer wrapper table ensures a consistent width across clients, and the main table holds the content. Inside, another table with two td elements, each set to width="50%", creates the columns. vertical-align: top is crucial for aligning content consistently.
The problem with modern CSS (like flexbox, grid, position, float beyond basic fallback) is that email clients have wildly different levels of support. Some, especially older versions of Outlook, will outright ignore them. Gmail, Outlook.com, Apple Mail, and iOS Mail have decent support, but it’s never 100%.
To overcome this, we inline most of our CSS. This means putting styles directly on the HTML elements using the style attribute, rather than in a <style> block in the <head>.
<td style="width: 50%; vertical-align: top; padding: 10px; font-family: Arial, sans-serif; font-size: 14px; color: #333333;">
<p style="margin: 0 0 10px 0;">This is the content for the first column. It needs to be responsive and look good on various email clients.</p>
<img src="placeholder.jpg" alt="Placeholder Image" width="100%" style="display: block;">
</td>
This is tedious, which is why tools called "CSS inliners" exist. You write your CSS in a <style> block, and the inliner tool moves it to the style attributes.
The core problem you’re trying to solve is compatibility. Email clients are the Wild West of rendering engines. Outlook (especially older Windows versions using Word’s rendering engine) is notoriously bad. WebKit-based clients (Apple Mail, iOS Mail, newer Outlook for Mac) are better. Gmail and Outlook.com are generally good but have their quirks.
The display: block; on the image is a common trick. By default, images are inline elements, which can sometimes introduce extra space below them in certain email clients. Making them block elements removes this.
The width: 100% on the image, combined with table-layout: fixed on the parent table and width: 50% on the td, creates a responsive column where the image scales with the column width.
The one thing most people don’t realize is how much !important is your enemy in email development. While it’s a standard CSS feature, many email clients (particularly older Outlook versions) have buggy implementations or ignore it entirely. Relying on specificity and inline styles is a more robust strategy.
The next hurdle you’ll likely face is ensuring your responsive design works on mobile devices, often involving media queries, which themselves have varying support.