1. Web Design
  2. Email
  3. Email Design

Build an HTML Email Template From Scratch

Scroll to top

The best way to understand any process is to carry it out yourself, from the ground up. Today, we’re going to do just that with email design, by building a simple HTML email template from scratch.

The HTML Email Template We’re Building

This is the HTML email template you’re looking for—feel free to fork the pen and use it yourself. Bear in mind that when we’re viewing this email HTML template through a web browser we’re much less likely to run into problems than with email clients.

“The sooner you stop fighting the quirks of email, the sooner you can use them to your advantage.” – Caity G. O’Connor

1. Begin Your HTML Email Document

To begin with, it’s worth mentioning where I pulled some of the resources from.

Now, as we discussed in the previous tutorial, you’ll need to begin your simple HTML email template with an HTML doctype, and the correct language for your subscribers. In this case, we are going to use the HTML5 doctype, set our language to English with <html lang="en">, and also include the XML and Microsoft Office namespaces (the xmlns bits). We are going to need these a few lines down, as I’ll explain.

1
<!DOCTYPE html>
2
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office">
3
<head>
4
    <meta charset="UTF-8">
5
	<meta name="viewport" content="width=device-width,initial-scale=1">
6
	<meta name="x-apple-disable-message-reformatting">
7
	<title></title>
8
	<!--[if mso]>

9
	<noscript>

10
		<xml>

11
            <o:OfficeDocumentSettings>

12
				<o:PixelsPerInch>96</o:PixelsPerInch>

13
			</o:OfficeDocumentSettings>

14
		</xml>

15
	</noscript>

16
	<![endif]-->
17
	<style>
18
		table, td, div, h1, p {font-family: Arial, sans-serif;}
19
		table, td {border:2px solid #000000 !important;}
20
	</style>
21
</head>
22
</html>

There are quite a few things in the code above, but it’s the bare minimum you need to ensure your final HTML in email renders beautifully everywhere.

Firstly, we have a few meta tags to ensure the right text encoding, viewport scaling across different mobile devices, and one to stop Apple from strangely adjusting the size in their mail apps.

Underneath the <title></title> tag you’ll see some code between <!--[if mso]> and <![endif]-->. Placing code inside those two tags means that only Microsoft Outlook on Windows will apply it (mso = “Microsoft Outlook”). In there, we have a small amount of XML that will ensure that PNG images display at the right size in Outlook on Windows. The xlmns settings that we put in the html tag ensures this code gets interpreted properly.

Underneath that, we have a style tag with just a couple of CSS rules. The first sets the font for all our main elements in the simple email template, and this is for the benefit of Gmail webmail, which will override our font settings unless we include this. If you end up changing your fonts later, be sure to make the change here too.

Finally, we are including table, td {border:2px solid #000000 !important;} which will draw a border on everything. This is purely so that we can see what we are doing as we build, and we’ll remove it at the end.

With that sorted, we can commence building the rest of the structure of our basic HTML email template.

2. Create the Body and Main Table

First, we’ll add an overall structure for our email, starting with a <body> tag. Add the code below directly underneath the </head> tag:

1
<body style="margin:0;padding:0;">
2
    <table role="presentation" style="width:100%;border-collapse:collapse;border:0;border-spacing:0;background:#ffffff;">
3
		<tr>
4
			<td align="center" style="padding:0;">
5
				Hello!
6
			</td>
7
		</tr>
8
	</table>
9
</body>

You can see the margin and padding on the body tag are set to zero to avoid any unexpected space in the HTML email framework.

We’ve also added a table with a width of 100%. This acts as a true body tag for our email, because the body tag is sometimes removed by email clients. Apply any “body” background colour that you want to this table tag.

All our tables will be set to role="presentation". This makes them more accessible, as it tells screen readers to treat it as a visual table, not a data table.

We have set border-collapse to collapse, and both border and border-spacing to zero to avoid any unexpected space in the table.

You’ll notice we are using <td align="center">, and if you’re already familiar with HTML you might be wondering why, since align is actually a deprecated HTML property. We use this in HTML email templates because email clients vary so widely in their level of CSS support, and often we still need to use deprecated HTML to ensure everything displays properly everywhere. In this instance, it is because Outlook for Windows does not obey margin:0 auto; in CSS to center things.

Finally, make sure you always set the padding on your table cells to zero in the inline styles, e.g. <td style="padding:0;">, otherwise, email clients will all add their own amount of padding. When we do add padding ourselves, we can adjust this value, but if there is no padding to be applied to any of the sides, you must explicitly set it to zero. 

Our first HTML email layout sectionOur first HTML email layout sectionOur first HTML email layout section

A Note on Using CSS Padding Shorthand

When using CSS padding on table cells, you can reliably write it three ways. Either specify one value, e.g. padding: 20px which will apply 20 pixels of padding to every side of your cell (top, right, bottom and left), or specify padding in pairs, i.e. padding: 10px 20px, which will add 10 pixels padding to both top and bottom, plus 20 pixels to both left and right. If neither of those are suitable, you should declare every side, i.e. padding: 10px 10px 0 5px. In all cases you must set each value, even if some of them are zero. Additionally, only specifying three values can have unpredictable results across email clients. 

Padding works reliably on table cells in all email clients, but if you are having trouble with padding, there is no need to resort to spacer GIFs. In a pinch you can use spacer divs or spacer cells. Just include a non-breaking space character (&nbsp;) inside, set a matching height and line height, and be sure to include mso-line-height-rule:exactly which will ensure Microsoft Outlook for Windows renders it at the pixel-perfect size. (If you are creating horizontal space, you need to specify a width instead of height, and may need to also add font-size:0;.) Here is an example or a spacer cell inside a row:

1
<tr><td style="line-height:10px;height:10px;mso-line-height-rule:exactly;">&nbsp;</td></tr>

And here is a spacer div:

1
<div style="line-height:10px;height:10px;mso-line-height-rule:exactly;">&nbsp;</div>

Adding the Main Table

Now let’s place a table of 602 pixels wide inside the container table.

600 pixels is a safe maximum width for your emails to display comfortably within most desktop and webmail clients on most screen resolutions, and we’re adding 2 pixels so we can have a 1-pixel border around the outside, which adds a pixel on either side.

We’ll replace our little ‘Hello!’ greeting with this table in our HTML email format example. 

1
<table role="presentation" style="width:602px;border-collapse:collapse;border:1px solid #cccccc;border-spacing:0;text-align:left;">
2
    <tr>
3
		<td style="padding:0;">
4
			Hello!
5
		</td>
6
	</tr>
7
</table>

Great! Now we have our outer table, and our main content table sitting inside, ready for some rows of content.

The container table for our HTML email layoutThe container table for our HTML email layoutThe container table for our HTML email layout

3. Create the HTML Email Template Structure and Header

In our email design we can see that the layout is divided into a few logical sections, so we’ll create a row for each.

Let’s duplicate the single row in the last table we added so that we have three in total, by copying everything between (and including) the <tr> and </tr> and pasting it two times underneath.

I’ve changed the “Hello!” text to read Row 1, Row 2 and Row 3 so it should now look like this:

1
<table role="presentation" style="width:602px;border-collapse:collapse;border:1px solid #cccccc;border-spacing:0;text-align:left;">
2
	<tr>
3
		<td style="padding:0;">
4
			Row 1
5
		</td>
6
	</tr>
7
	<tr>
8
		<td style="padding:0;">
9
			Row 2
10
		</td>
11
	</tr>
12
	<tr>
13
		<td style="padding:0;">
14
			Row 3
15
		</td>
16
	</tr>
17
</table>
Extra rows in our HTML email layoutExtra rows in our HTML email layoutExtra rows in our HTML email layout

Now we’ll colour them according to the design by adding a background CSS property to the style tag. Always remember to use the full six characters of a hexadecimal code like #ffffff, as three-character shorthand like #fff won’t always work in all email clients.

1
<table role="presentation" style="width:602px;border-collapse:collapse;border:1px solid #cccccc;border-spacing:0;text-align:left;">
2
	<tr>
3
		<td style="padding:0;background:#70bbd9;">
4
			Row 1
5
		</td>
6
	</tr>
7
	<tr>
8
		<td style="padding:0;">
9
			Row 2
10
		</td>
11
	</tr>
12
	<tr>
13
		<td style="padding:0;background:#ee4c50;">
14
			Row 3
15
		</td>
16
	</tr>
17
</table>
Colored rowsColored rowsColored rows

Ok, next up in our sample HTML email design we’re going to focus on Row 1. On the cell, let’s change the padding from 0 to 40px 0 30px 0. Then inside the cell we’ll insert our image:

1
<td align="center" style="padding:40px 0 30px 0;background:#70bbd9;">
2
	<img src="images/h1.png" alt="" width="300" style="height:auto;display:block;" />
3
</td>

Always specify the width of your images using the HTML width attribute rather than CSS, e.g. width="300" as seen above, rather than style="width:300px;". If you don’t, Microsoft Outlook for Windows will display your image at its physical size. 

We have also set the image height to auto to avoid any squishing, and display to block, which prevents gaps from appearing underneath it in some email clients.

Finally, if your image contains important information that isn’t mentioned in your email’s text, be sure to add a description of it to the alt tag so that it will be announced by screen readers to those using them.

Images don’t always load and alt text isn’t always visually displayed as a fallback, so any crucial information should always be included as live text in your simple email template rather than being embedded in an image.

And that’s our HTML header done!

The html email header along with imageThe html email header along with imageThe html email header along with image

4. Create the Content Area for Your HTML Email Template

Moving on from the header, let’s now concentrate on our HTML template for the email body or the email’s content area. First off, we’ll add some padding to the Row 2’s cell so that the table inside has some space around it, as per our design, so that it now looks like this:

1
<tr>
2
	<td style="padding:36px 30px 42px 30px;">
3
		Row 2
4
	</td>
5
</tr>
Added padding to the middle cellAdded padding to the middle cellAdded padding to the middle cell
Added padding to the middle cell

Now we’ll replace the “Row 2” text with another table to nest our main content inside. When building HTML email using tables, we need to nest them because colspan and rowspan are not widely supported across email clients.

1
<table role="presentation" style="width:100%;border-collapse:collapse;border:0;border-spacing:0;">
2
	<tr>
3
		<td style="padding:0;">
4
			Row 1
5
		</td>
6
	</tr>
7
	<tr>
8
		<td style="padding:0;">
9
			Row 2
10
		</td>
11
	</tr>
12
</table>

We’ve set the width of this table to 100%. It’s good practice to use percentage widths rather than using a pixel value wherever possible in formatted email templates because this will help you further down the track if you want to make your email responsive, or even if you simply need to adjust the width of your email later on. Percentage widths will automatically adapt to a new container size, whereas pixel widths would all need to be individually updated.

Two nested rows for our main contentTwo nested rows for our main contentTwo nested rows for our main content
Two nested rows for our main content

Now we’ll add our content to the top row, which is a heading, a paragraph of text, and a final paragraph with a link inside. At this stage, we aren’t adding any styling at all to these elements.

Added content and padding to the top rowAdded content and padding to the top rowAdded content and padding to the top row

Replace the “Row 1” text with the following:

1
<h1>Creating Email Magic</h1>
2
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tempus adipiscing felis, sit amet blandit ipsum volutpat sed. Morbi porttitor, eget accumsan et dictum, nisi libero ultricies ipsum, posuere neque at erat.</p>
3
<p><a href="http://www.example.com">In tempus felis blandit</a></p>

Next, we’re going to add our two columns of content to Row 2. Because we want a gap between these two cells, we’ll create a three-column table with an empty cell between the two outer columns. There are a few ways to create this basic email template layout, but this one is the most reliable for our purposes.

As much as I like to stick to percentages, when you have content that is a specific size, it can be tricky to convert it to a percentage (in this example, the columns would be 48.1% which could become confusing). For this reason, since our two images are 260px wide, we’ll create columns that are also 260px wide, with a 20px margin cell in the middle. (This will total 540px, which is the 600px width of our table minus the padding of 30px on either side.) Be sure to zero your font-size and line-height and add a non-breaking space character &nbsp; in the middle cell.

We’ll also set the vertical-align to top for both cells so that they will vertically align to the top, even if one column has more text than the other. The default vertical alignment is middle.

Replace “Row 2” with this table:

1
<table role="presentation" style="width:100%;border-collapse:collapse;border:0;border-spacing:0;">
2
	<tr>
3
		<td style="width:260px;padding:0;vertical-align:top;">
4
			Column 1
5
		</td>
6
		<td style="width:20px;padding:0;font-size:0;line-height:0;">&nbsp;</td>
7
		<td style="width:260px;padding:0;vertical-align:top;">
8
			Column 2
9
		</td>
10
	</tr>
11
</table>
Two columns to content row twoTwo columns to content row twoTwo columns to content row two

Now let’s add our images and content to those columns. Margins are very well supported on <p> tags across all email clients, so we will wrap our text and images in <p> tags and adjust the spacing between them using margin later when we add all our text styling.

Let’s add content to Columns 1 and 2 so that the whole table now looks like this:

1
<table role="presentation" style="width:100%;border-collapse:collapse;border:0;border-spacing:0;">
2
	<tr>
3
		<td style="width:260px;padding:0;vertical-align:top;">
4
			<p><img src="images/left.gif" alt="" width="260" style="height:auto;display:block;" /></p>
5
			<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tempus adipiscing felis, sit amet blandit ipsum volutpat sed. Morbi porttitor, eget accumsan dictum, est nisi libero ultricies ipsum, in posuere mauris neque at erat.</p>
6
			<p><a href="http://www.example.com">Blandit ipsum volutpat sed</a></p>
7
		</td>
8
		<td style="width:20px;padding:0;font-size:0;line-height:0;">&nbsp;</td>
9
		<td style="width:260px;padding:0;vertical-align:top;">
10
			<p><img src="images/right.gif" alt="" width="260" style="height:auto;display:block;" /></p>
11
			<p>Morbi porttitor, eget est accumsan dictum, nisi libero ultricies ipsum, in posuere mauris neque at erat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tempus adipiscing felis, sit amet blandit ipsum volutpat sed.</p>
12
			<p><a href="http://www.example.com">In tempus felis blandit</a></p>
13
		</td>
14
	</tr>
15
</table>

Here we’ve set the width of the images using the HTML width attribute again, just like we did when we inserted the header image.

Images in the columnsImages in the columnsImages in the columns
Images in the columns

Now we’ll add our padding to the footer row in this HTML mailer we're creating.

1
<tr>
2
	<td style="padding:30px;background:#ee4c50;">
3
		Row 3
4
	</td>
5
</tr>
Padding to the footer rowPadding to the footer rowPadding to the footer row
Padding to the footer row

Inside that cell, we’ll replace the “Row 3” text with another table to get two columns, each 50% wide, with the left set to align="left" and right to align="right" so that the content in each will be pinned to those sides and give us a balanced email design.

1
<table role="presentation" style="width:100%;border-collapse:collapse;border:0;border-spacing:0;">
2
	<tr>
3
		<td style="padding:0;width:50%;" align="left">
4
			Left Column
5
		</td>
6
		<td style="padding:0;width:50%;" align="right">
7
			Right Column
8
		</td>
9
	</tr>
10
</table>
Two columns for the footerTwo columns for the footerTwo columns for the footer
Two columns for the footer

Replace “Left Column” with a paragraph of text:

1
<p>&reg; Someone, Somewhere 2021<br/><a href="http://www.example.com">Unsubscribe</a></p>

We’ll create another little table for our social media icons, as it’s the best way to get the most precise spacing that renders properly everywhere. Replace the “Right Column” text with the table below.

You’ll notice we aren’t specifying a table width, and this is so that the width of the table will be determined by the cells within. They are each 38px wide (the width of our icons) plus 10px padding on the left.

1
<table role="presentation" style="border-collapse:collapse;border:0;border-spacing:0;">
2
	<tr>
3
		<td style="padding:0 0 0 10px;width:38px;">
4
			<a href="http://www.twitter.com/"><img src="images/tw.png" alt="Twitter" width="38" style="height:auto;display:block;border:0;" /></a>
5
		</td>
6
		<td style="padding:0 0 0 10px;width:38px;">
7
			<a href="http://www.facebook.com/"><img src="images/fb.png" alt="Facebook" width="38" style="height:auto;display:block;border:0;" /></a>
8
		</td>
9
	</tr>
10
</table>
Table for social media iconsTable for social media iconsTable for social media icons
Table for social media icons

And there we have it; our HTML email template layout is complete!

6. Style the Text in Your Simple HTML Email Template

Styling the text within our HTML email template is a really important step. First, let’s look at the top row of content with our h1 and introductory text. 

Important Note When Using Paragraph and Heading Tags

When using paragraph and heading tags (p, h1, h2, etc.) you must specify your top and bottom margin settings. Otherwise, each email client will apply their own wildly different default margins to these elements. You also need to make sure your top and bottom margins are set to zero if you don’t want any at all, in which case you would set your heading to margin:0;. If you only want a bottom margin, you should still set the top margin to zero, e.g. margin:0 0 10px 0;

With that in mind, we’ll set our desired margins on all our tags, and we also want to set the text colour to be #153643, which we can apply to the cell, as everything inside will inherit that colour. After these changes, the whole cell looks like this:

1
<td style="padding:0 0 36px 0;color:#153643;">
2
	<h1 style="font-size:24px;margin:0 0 20px 0;font-family:Arial,sans-serif;">Creating Email Magic</h1>
3
	<p style="margin:0 0 12px 0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tempus adipiscing felis, sit amet blandit ipsum volutpat sed. Morbi porttitor, eget accumsan et dictum, nisi libero ultricies ipsum, posuere neque at erat.</p>
4
	<p style="margin:0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;"><a href="http://www.example.com" style="color:#ee4c50;text-decoration:underline;">In tempus felis blandit</a></p>
5
</td>

You’ll notice above that we have also set the font-family on every individual h1 and p element, and you might be wondering why we can’t just set this on the body or table tag. This is because some webmail clients will override your font if you don’t set them inline on each paragraph or heading element. There are other considerations and approaches to this issue, but for simplicity’s sake and to ensure our HTML email design renders perfectly everywhere at this stage, we will set it inline on each element.

Now, moving down to our two-column area, add the color to each of the 260px wide cells so that they both look like this:

1
<td style="width:260px;padding:0;vertical-align:top;color:#153643;">

As above, we’ll add some text styling and margins to our paragraphs and links, and set a base font size to the entire table. Altogether, the table now looks like this:

1
<table role="presentation" style="width:100%;border-collapse:collapse;border:0;border-spacing:0;">
2
	<tr>
3
		<td style="width:260px;padding:0;vertical-align:top;color:#153643;">
4
			<p style="margin:0 0 25px 0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;"><img src="images/left.gif" alt="" width="260" style="height:auto;display:block;" /></p>
5
			<p style="margin:0 0 12px 0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tempus adipiscing felis, sit amet blandit ipsum volutpat sed. Morbi porttitor, eget accumsan dictum, est nisi libero ultricies ipsum, in posuere mauris neque at erat.</p>
6
			<p style="margin:0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;"><a href="http://www.example.com" style="color:#ee4c50;text-decoration:underline;">Blandit ipsum volutpat sed</a></p>
7
		</td>
8
		<td style="width:20px;padding:0;font-size:0;line-height:0;">&nbsp;</td>
9
		<td style="width:260px;padding:0;vertical-align:top;color:#153643;">
10
			<p style="margin:0 0 25px 0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;"><img src="images/right.gif" alt="" width="260" style="height:auto;display:block;" /></p>
11
			<p style="margin:0 0 12px 0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;">Morbi porttitor, eget est accumsan dictum, nisi libero ultricies ipsum, in posuere mauris neque at erat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tempus adipiscing felis, sit amet blandit ipsum volutpat sed.</p>
12
			<p style="margin:0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;"><a href="http://www.example.com" style="color:#ee4c50;text-decoration:underline;">In tempus felis blandit</a></p>
13
		</td>
14
	</tr>
15
</table>

Finally, we’ll style the footer. Firstly, we’ll add some font styling to the main footer table, inside our red footer cell with the 30px padding, so that it now reads:

1
<td style="padding:30px;background:#ee4c50;">
2
    <table role="presentation" style="width:100%;border-collapse:collapse;border:0;border-spacing:0;font-size:9px;font-family:Arial,sans-serif;">

In the left column of this table, we can update our paragraph and link to include style and colour:

1
<p style="margin:0;font-size:14px;line-height:16px;font-family:Arial,sans-serif;color:#ffffff;">
2
	&reg; Someone, Somewhere 2021<br/><a href="http://www.example.com" style="color:#ffffff;text-decoration:underline;">Unsubscribe</a>
3
</p>

And on our social media icons, we’ll style each link to be white, so that if the images don’t load, any alt text will be visible on the red background. Adjust each link so that they look like this in the HTML code for your email template:

1
<a href="http://www.twitter.com/" style="color:#ffffff;">

and

1
<a href="http://www.facebook.com/" style="color:#ffffff;">
Almost thereAlmost thereAlmost there
Almost there!

And there we have it! Everything is in.

7. Run Some Tests to Make Sure Your Simple Email Template Works

At this point, it’s a good idea to run your HTML code through an email testing service like Litmus, or Email on Acid. Leaving the borders on all the tables and cells can be helpful to see what’s happening in each email client. (Depending on how you are testing your email, you might need to remotely host your images first, and insert the full remote URLs for each image into your code. Refer to your testing service’s website to learn how to test your HTML mailer.)

Here are some of my test results from Email on Acid:

Now it’s time to turn off the borders and see the email design looking beautiful. In the style tag in the head, remove the line that reads:

1
table, td {border:2px solid #000000 !important;} 
Borders turned offBorders turned offBorders turned off
Borders turned off

And that’s it! 

You’ve Created a Simple HTML Email!

Before we call it a day, if you have used any comments in your CSS in the head of your file for any reason, get rid of them. Some email clients can choke on CSS comments so it’s wisest not to include them.

Now is a good time to do a final test with Litmus, or Email on Acid, and then your HTML email is ready to send!

Learn More About Creating Email Templates in HTML

To take what you’ve learned to the next level! Check out our Mastering HTML Email learning guide for more tutorials on HTML email templates, email design, coding responsive email, accessibility, marketing, transactional email designs, email service providers (ESPs), development workflow tips, and more!

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.