Implementing emails in 2021: Basics & how to test generated emails

We wanted to give our emails a fresh look to match the new design of our product and brand. Outlook did not agree. What have we learned about email formatting, and did we succeed in the end?

Martin Hejtmanek

Martin Hejtmanek

Published on Jul 14, 2021

If you were ever asked to develop an email and made it work for various email clients, you know what a hell it can be. Despite almost giving up half the way through, we succeeded! We learned a lot and even found some new ways to cope with the tough parts of the desired email design.

In this article, I will present you with a summary of my findings. Hopefully, they will make your day brighter...or your emails.

We have recently redesigned the UI of our product and have given it a shiny new look:

New UI in Kentico Kontent

The email notifications sent by the system on various occasions were the last missing piece of the redesign. As our solution is a SaaS content management system, it generates not only basic user account-related emails but also notifications related to workflow and review, such as comments and tasks associated with a specific piece of content.

All these emails are generated in the .NET back end with Razor templates, so, unlike some one-off marketing email, we couldn’t just stitch a bunch of images together using any design we liked. We actually needed to generate some layout on the fly and populate it with various content.

Why is developing robust emails such a big deal?

It should be a simple task for an average web developer, because, after all, emails support the HTML body, right?

Well, if you ever wanted to use a time machine, this is about as close as you can get. Start developing some emails, try to make them compatible with various email clients out there (even the recent ones), and you got yourself a ticket to the year 2000 and earlier. Internet Explorer stuff all over again, and even worse. It comes down to Outlook and its HTML rendering engine, which surprisingly does not render HTML and only imports it.

A real example, our own emails

Here is an example of such email design from our UX team where you may notice some aspects that seem trivial in the browser world but pretty complex in the email client world once you try to implement them in a reliable way.

Those features are:

  • Containers with rounded corners
  • Rounded buttons with shadow
  • Rounded tags aligned vertically with the text
  • Some images
  • Global email layout centered with max-width.

Here is an example of what we got from our UX designers:

New email design

Spoiler alert: We managed to implement all of that, and once you finish this series of articles, you will know how to do it, too.

Outlook is still your biggest enemy, so keep it close

As much as I love all the various Microsoft technologies and products, I can sincerely say I hate Outlook, even though I’ve conquered it. It’s official, and I don’t feel any shame for it at all.

The problem with it is that it uses MS Word as a rendering engine for HTML. Yes, you read it right, MS Word! MS Word!...Insane. I can guess why. Its developers got a free rich text editor...but at what cost?

I have to say that this applies only to Outlook on Windows. On a Mac, it uses a browser-based rendering engine.

Just to give you some idea, this is what Outlook provides for a pretty standard HTML when Outlook-specific hacks are missing. It is not entirely ugly but doesn’t match the required design in many aspects.

No Outlook hacks

This basically means that it cannot do most of the typical things you are used to in HTML nowadays. It should have been revamped a long time ago (like 2010?) to a decent rendering engine, but it wasn’t. So we have to deal with it all over again and use obsolete technologies such as VML.

The saying “Keep your friends close and your enemies closer” can be applied here. There is no escape from it—you can only get along with it, accept your faith, learn, and then beat it with your excellence!

Having said that, VML needs to be your friend on this journey. Because if you know how VML works and what is possible, you’ve already won half of your battle.

I will now show you how you can implement different aspects of your emails...at least for the things we have managed to achieve during our email redesign...but even that’s something!

Quick and bulk testing: PaperCut SMTP for help

To begin, you need an efficient way to get your emails to the email client or to quickly check them.

PaperCut SMTP is a great tool that creates a localhost SMTP server to capture your emails.

What we did is we captured all emails generated and asserted by our unit tests and let the test instance send them automatically to localhost upon each test execution. All you need to do is to create a new instance with new SmtpClient("localhost") and use it to send the email. This dramatically improves the speed of validating changes in the emails.

PaperCut provides a pretty good view of the email with an HTML rendering engine, so it is a good starting point to check that your email looks the way you expect it to.

BUT...it doesn’t validate the Outlook view at first glance. Luckily, you can open the PaperCut target folder and open the .eml files from there in Outlook. Manually, one by one—or with a script.

My Outlook is connected to an Exchange server that automatically syncs all the emails in the Inbox with all the other devices, so having these in Outlook gives you a pretty good entry for simple testing on these different devices. You just need to connect them to the same email account.

By )adjusting the SmtpClient config, we dump the same set of emails to Gmail for testing through its SMTP.

new SmtpClient("smtp.gmail.com") {
  EnableSsl = true,
  Credentials = new System.Net.NetworkCredential(userName, password),
  Port = 587
}

HTML files for quick experiments

Besides testing the actual .eml files, you can also experiment with their HTML form if you dump them to the local file system instead, or along with the SMTP server.

Firstly, you can open and browse those easily in a real browser such as file:///c:/temp/emails and experiment with adjusting CSS and markup in there for HTML-based email clients.

Secondly, there’s a neat trick in Outlook. If you drag that HTML file to the list of messages in Outlook, it creates a new draft message from it, but it first runs it through the HTML import to Word, which gives you an almost perfect preview of how the message will look. I am saying almost, as I noticed some slight ~1px differences in there compared to actually sent emails, but it’s still a good enough approximation. 

This way, you can easily iterate over all kinds of experiments with the Outlook exceptions and VML.

Note: You can also drag these files to the new file dialog of MS Word, and it opens as a Word document (also converted from HTML), but that doesn’t offer the exact view as in Outlook, not even on the same machine.

External validation services

It’s worth noting that services such as https://www.emailonacid.com/ or https://www.litmus.com/ can provide you with previews so you know how your email contents will look in different email clients.

The absolutely basic stuff you should know

Now that you’ve learned a few pointers on how to effectively test and experiment with emails, it’s time to dive in.

Linked images seem to be the best

We tried various approaches. Inlining the images with Base64 seemed to work best at first, but after more thorough testing, we found out that Outlook has a problem with PNG transparency in inline images, and Gmail doesn’t support inlined images at all (perhaps for security reasons), so we reverted back to just linked images.

Do not expect custom fonts to work

This one is simple...there is no way to make custom fonts work in all email clients, so you’d better give up now to save yourself some time. You may be able to make few clients work with a custom linked web font based on the existing resources, but is it really worth it? I wouldn’t say so.

We are using font-family: "Helvetica", Helvetica, Arial, sans-serif; to best match our app font, which is actually GT Walsheim Pro.

You can read more about email fonts here.

Be a bit bipolar, use conditions (Outlook vs. others)

Outlook is bad and totally different than the others, right? So the deal is basically to develop emails for “normal” HTML email clients and then “separately” for Outlook.

The rule of thumb is to basically have two versions of the email in one, not interfering with one another.

We are using two simple conditions to achieve this:

Outlook only code:

<!--[if mso]>
<p>Something for Outlook only</p>
<![endif]-->

Code to show only in other than Outlook clients:

<!--[if !mso]><!-->
<p>Something for everything but Outlook</p>                
<!--<![endif]-->

Note how, in the second condition, you need to use extra comment wrapping to properly ignore otherwise invalid markup while also making a valid condition for Outlook.

How to center the content in Outlook

In normal (HTML mature) clients, you can use standard max-width and margin-auto. For Outlook, you’ll need to use a special wrapper.

Include this part of code under BODY to get a centered email with a maximum of 600px width in all email clients:

<!--[if mso]>
<center>
<table><tr><td width="600">
<![endif]-->
<div style="width: 100%;display:block;margin:0 auto;max-width:600px;">
        HERE COMES THE EMAIL CONTENT
</div>
<!--[if mso]>
</td></tr></table>
</center>
<![endif]-->

You can also see here how you can easily apply a conditional wrapper in the case of Outlook.

Always inline CSS, but with one exception

As most of the email clients do not process styles in HEAD, and only some process styles in BODY (e.g., Outlook—yay!), it is best to inline the CSS into the HTML to make sure everything works.

We use the PreMailer library to do that. But be careful and make sure that:

  • Inlining doesn’t remove comments, as you will need them to drive Outlook exceptions.
  • Inlining doesn’t remove style tag in the body meant for Outlook (see below).

Also, forget about more complex CSS selectors, PreMailer supports some, but in a very limited scope. I think we only used :first and :last. If you don’t inline the CSS, clients won’t support it anyway.

There is one exception to this rule. Outlook needs the font family applied globally, so keep this one style tag within the BODY of the email. With the font of your choice, of course.

<!--[if mso]>
<style type="text/css">
    body, table, td, p, h1, h2, h3, span, a { font-family: "Helvetica", Helvetica, Arial, sans-serif !important; }
</style>
<![endif]-->

VML for Outlook

This is a given. Whatever isn’t possible with HTML code needs to be done in VML in Outlook—unless you want to mimic it with an image or omit it completely.

Make sure to add the namespace directives to your HTML tag before using any of the VML objects in your emails.

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">

Proper scaling and compatibility mode for Outlook

In addition to other Outlook things, I recommend using the following two adjustments you place in your HEAD tag.

Add compatibility metadata for IE to use the latest version. Without it, advanced stuff like rounded corners would not work if someone opened the email using the browser option, because IE doesn't know VML and its previous version doesn't know border radius. Thanks to this compatibility metadata, it uses the latest version as well as the HTML and CSS you have for standard email clients.

<meta http-equiv="X-UA-Compatible" content="IE=edge">

Add Office document metadata and viewport to enforce proper scaling. Without this, your image sizes or VML object placements may be distorted and inconsistent.

<!--[if gte mso 15]>
<xml>
    <o:OfficeDocumentSettings>
    <o:AllowPNG/>
    <o:PixelsPerInch>96</o:PixelsPerInch>
    </o:OfficeDocumentSettings>
</xml>
<![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1">
    

Design system & components

Find a way to avoid code repetition and copy-pasting of anything that has some Outlook exceptions. If you don’t, you will soon get lost in tables and HTML conditions duplicated all over the place.

We built a minimalistic design system with a few key components that abstract away the complexity of email client dependencies and customizations for Outlook.

Our own set of components consists of:

  • Box - Think of a DIV with all the goodies you are used to—border, background, inner and outer spacing, and even a border radius!
  • Stack - A list of items with a defined spacing between them, horizontal or vertical.
  • Button - Simply a button with rounded corners, and even a shadow!
  • Workflow label - “A pill” (tag) with defined color, text, and rounded corners placed inline within the text.
  • Mention - Either just colored text or “a pill” similar to the workflow label if it’s you who’s mentioned.
  • Heading 2 - We only need special handling for H2 as we don’t use smaller headings, and H1 is always at the top of the email body where we don’t need special handling for spacing in Outlook. Everything else related to the normal text is used. 

Here are some examples of how individual components map to the design:

Components and the design
Components and the design version 2

And this is how we typically use them in the Razor code based on whether they represent a container or a standalone entity:

@using (Kontent.BeginBox(new BoxModel(
    padding: Spacing.XL,
    backgroundColor: Color.Desk
) {
    Paddings = { X = Spacing.XL, Y = Spacing.L }
}))
{
    <img width="150" height="46" class="header__img" alt="Kontent.ai" src="@Icons.KontentLogo">
}

@Kontent.Button(Model.GoToActionUrl, "Open subscription details")

On the technical side, we are using Razor partial views or simple helpers returning HTML strings to render their markup.

Useful resources

You need to fight this battle with the proper knowledge to win. Here is a list of resources I found extremely useful during our journey. They will assist you in avoiding dead ends and provide you with suggestions for suitable alternatives.

  • https://www.campaignmonitor.com/css/ - A huge list of features supported by individual email clients, as well as a brief description of each email client and its specifics.
  • https://www.caniemail.com/ - Basically “can I use” for emails. Very useful if you are interested in a specific feature.
  • https://buttons.cm/ - Rounded buttons. But I will tell you even more in one of my next articles.
  • https://backgrounds.cm/ - Background images in emails, we didn’t use these, but still nice to see some concepts, e.g., expanding VML object to the full width.
  • https://www.w3.org/TR/NOTE-VML - Your primary cannon for the Outlook battle. VML is pretty flexible (kinda old-fashioned SVG) and offers much more than you normally see while searching for how to do X and Y in emails. I will show you in my upcoming articles.

There is a lot more, just Google the usual suspect keywords (email, Outlook, and the topic you are up to), just expect that most of these will give you the rather specific advice that you may need to bend a bit using the knowledge from the above-mentioned sources.

My best advice overall is: Think about the concepts, not just the final code.

Are we there yet? 

This is just the beginning. The following articles in this series will show you the implementation details of some of those individual components and their specific challenges. Some of them required me to create original solutions I couldn’t Google anywhere. Find the respective parts below.

In the next article, I will show you how you can make rounded buttons and, most importantly, how seemingly impossible shadows are actually possible.

Subscribe to the Kontent.ai newsletter

Get the hottest updates while they’re fresh! For more industry insights, follow our LinkedIn profile.