In this article I am going to put to the test the basic bulletproof button techniques, and also introduce a couple of new ideas I had during the testing process. Email buttons are hard to test, because passing visual tests like Litmus or Email on Acid are not enough. It is fundamental as well to click those buttons to confirm that they are bulletproof indeed. I have done that cumbersome work for you, and I share the results in short animations, so you have a reliable proof.

This blog post is the 7th article of the Modern HTML Email Tutorial series, which is a bi-weekly article series, where we share new discoveries and approaches about email coding. Our last post discussed content images, and in the upcoming post you can read about background-images in Email HTML. Furthermore, there is food for thoughts on marketing topics in our Email Design Basics for Email Marketers series. If you wish to be updated on the new posts, please subscribe to our newsletter!

This article introduces a new approach for call-to-action buttons - the line-height based button, which has very good support across clients, and displays well, where other methods has drawbacks in contrast. Let's get started!

Visual Test on the Basic Methods

The basis of my tests is the example below, but first I am going to present the steps leading towards this:

The ground zero, I started from, was Jason Rodriguez's - well respected author and Product manager @ Litmus - post on bulletproof buttons. At Litmus, they recognize 4 basic types of bulletproof buttons, namely VML-based, padding-based, border-based and padding + border-based bulletproof buttons. First, I took these basic types and tried to understand the key similarities and differences. I created a template which includes all four button types.

Examining the preview above and the previews of the visual test, we can see that email clients on Android render the buttons with the same size, on other mobile clients and web based clients they have different sizes. On desktop clients there are more serious compatibility problems besides that:

In some cases only the link shows up from the button, in other cases the entire button is missing. This occurs when we want to support Word-based Outlooks and Lotus Notes. I am going to revisit this topic, and apply fixes in the next section.

You can check out the full source code of this step on Github.

Litmus test results

Possible Fixes for the Basic Bulletproof Button Types

The previews showed, that there are two major incidents that can ruin our day (or let's hope that just our email display): missing buttons and bare links showing up without styling. These two only happen on different versions of Outlook and Lotus Notes. We are going to handle these problems in the following sub-sections one-by-one.

Fix for the IE-based Outlooks

At first, I wanted the buttons to have a similar look and define the common properties of them. This way they only differ in relevant aspects. After some careful examination of the code-base and the previews, I was ready to conclude and apply the necessary properties.

The differences are straightforward in these methods, as it is reflected in each method's name. So VML-based technique uses VML, and padding-based technique uses padding on the table cell (as padding is not supported in a tags in Outlook clients), and so on.

The similarities were a little harder. But I could identify the shared properties, which are important to be set on the a tag.

Therefore, I applied the following on every link ( anchor element):

style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none;line-height:54px;"

I have done this for the Litmus button types, and later to the button types I have come up with, as well. For buttons that have padding or border set, line-height had to be reduced, but overall, the buttons height was aimed to be 54px in each case.

Now, the buttons in the example look pretty much the same and as a result of the line-height property, older IE-based Outlooks are fixed.

This step's benefit is the new technique as you will see later.

You can check out the full source code of this step on Github.

You can also review the influence of this step on Litmus

Fix for Word-based Outlooks

As the previous preview shows below, the buttons only appear for the VML and padding-based techniques in Word-based Outlooks.

The VML technique is specifically designed for Outlook, so it is quite understandable that it works. But why does it work with padding-based buttons?

My suspicion was that it is due to the padding on the td element and I could confirm in a separate test when I applied padding on all of the basic button types.

So, if we complete every button with padding on the a tag, we can show the background of the button. But what is more interesting here, that there is no title on these "padding-based buttons", anyway. As I wanted to fix this, a more general solution came into life to fix button display, and this step is about that.

Originally, I tried to wrap the button's text in a span and apply different styles until the text shows up - with no success. Next, I tried to wrap the text in an element with more semantic meaning. The first choice was a h1 element, it had the highest probability to be rendered. It did, but I am only showing you the more modest version with a p tag.

The border-based button would look like this in the test code:

<table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td> <a href="http://litmus.com" target="_blank" style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none;line-height:30px; border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; background-color: #EB7035; border-top: 12px solid #EB7035; border-bottom: 12px solid #EB7035; border-right: 18px solid #EB7035; border-left: 18px solid #EB7035; display: inline-block;"> <p style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none;"> I am a button → </p> </a> </td> </tr> </table> </td> </tr> </table>

So, here we have a set of nested tables. In the inner table there is a table cell, which has no property defined, inside that an a tag, with my default settings described previously. There are also border properties defined according to the different direction, and the display property, which you would set inline-block for a tags. You may notice, that I set my standard font properties on the p element as well, as omitting that causes font problems on Android devices:

To have an overview of what we have achieved, here is Outlook 2010's preview, before...



and after...

... this fix. Of course, there are some aesthetic concerns to reduce the padding on the padding-based and padding + border-based buttons padding property, but right now I am satisfied with the fact, that without VML, we have fairly well appearing buttons in Outlook.

You can check out the full source code of this step on Github.

Litmus test results

Fix for Lotus Notes Displays

On Lotus Notes versions, padding-based and padding + border based buttons have the greatest support. For these techniques the anchor tag shows up and the styles applied on it. VML- and border-based buttons on the other hand, either do not show up at all, or only the bare link displays.

It seemed logical, that if some buttons show correctly, there may be a way to fix the others. I could accomplish this, by closely examining the shared properties of the well displaying buttons, and trying out each variations that seemed to have potential. I will not bore you with the details, just share the solution. The needed property is the bgcolor attribute on the td element.

After this step, a more promising preview becomes available:

If you need to support various versions of Lotus Notes, you need to add some additional styles to decorate your buttons. After this step we can conclude, that coloring the table cell is essential to have good button display in Lotus Notes.

Conclusion

To sum up this section, we looked at the basic button types recommended by Litmus. Based on the visual tests we solved display problems in three steps, by applying:

line-height,

p tag with optional styles,

tag with optional styles, bgcolor attribute on table cell.

In the next section, I am going to share the discoveries of my research by introducing new possible ways for bulletproof HTML email buttons and also examine the visual test results.

You can check out the full source code of this step on Github.

Litmus test results

Researching Alternative Methods with Benefits

In my research, I found a huge number of button codes, but most of them was originated from the four basic types mentioned before. I read community discussions on various blogs and Stack Overflow. From my readings two new method came into light ( unfortunately they are not recommended by W3C standards). From the fixes discussed, I kindly present the new line-height based bulletproof button as well:

Line-height based method: setting the width and line-height in inline styles,

and in inline styles, Native button based method: nesting a native button element inside an a tag (not W3C recommended),

element inside an tag (not W3C recommended), Table-based method: nesting an entire table in an a tag (not W3C recommended).

After gathering these various methods, and implementing the "standardization styles" discussed in previous sub-section, the code that is sent to the email clients looks like this:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Button test</title> <style> html, body, table, tbody, tr, td, div, p, ul, ol, li, h1, h2, h3, h4, h5, h6 { margin: 0; padding: 0; } body { margin: 0; padding: 0; font-size: 0; line-height: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } table { border-spacing: 0; mso-table-lspace: 0pt; mso-table-rspace: 0pt; } table td { border-collapse: collapse; } .ExternalClass { width: 100%; } .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div { line-height: 100%; } /* Outermost container in Outlook.com */ .ReadMsgBody { width: 100%; } img { -ms-interpolation-mode: bicubic; } </style> <style> .container600 { width: 600px; max-width: 100%; } @media all and (max-width: 600px) { .container600 { width: 100% !important; } } @media all and (max-width: 599px) { .reorder { width: 100% !important; } } </style> <!--[if gte mso 9]> <style> .ol { width: 100%; } </style> <![endif]--> </head> <body> <center> <!--[if gte mso 9]><table width="600" cellpadding="0" cellspacing="0"><tr><td> <![endif]--> <table class="container600" cellpadding="0" cellspacing="0" border="0" width="100%" style="width:calc(100%);max-width:calc(600px);margin: 0 auto;"> <tr> <td width="100%" style="text-align: left;"> <!-- |||||||||||||||||| 1) VML-BASED BUTTONS |||||||||||||||||| --> <h4 style="font-family:Arial;font-size:20px;line-height:22px; padding-top:10px;padding-bottom:10px">1) VML-BASED BUTTONS</h4> <table width="100" border="0" cellspacing="0" cellpadding="0"> <tr> <td bgcolor="#e9703e"> <div> <!--[if mso]> <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="http://litmus.com" style="height:36px;v-text-anchor:middle;width:150px;" arcsize="5%" strokecolor="#EB7035" fillcolor="#EB7035"> <w:anchorlock/> <center style="color:#ffffff;font-family:Helvetica, Arial,sans-serif;font-size:16px;">I am a button →</center> </v:roundrect> <![endif]--> <a href="http://buttons.cm" style="background-color:#EB7035;border:1px solid #EB7035;border-radius:3px;color:#ffffff;display:inline-block;font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none;line-height:54px;text-align:center;width:150px;-webkit-text-size-adjust:none;mso-hide:all;">I am a button →</a> </div> </td> </tr> </table> <!-- |||||||||||||||||| 2) PADDING-BASED BUTTONS |||||||||||||||||| --> <h4 style="font-family:Arial;font-size:20px;line-height:22px;padding-top:10px;padding-bottom:10px">2) PADDING-BASED BUTTONS</h4> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td bgcolor="#EB7035" style="padding: 12px 18px 12px 18px; -webkit-border-radius:3px; border-radius:3px" align="center"><a href="http://litmus.com" target="_blank" style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none; display: inline-block;"><p style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none;line-height:30px;"> I am a button → </p></a></td> </tr> </table> </td> </tr> </table> <!-- |||||||||||||||||| 3) BORDER-BASED BUTTONS |||||||||||||||||| --> <h4 style="font-family:Arial;font-size:20px;line-height:22px;padding-top:10px;padding-bottom:10px">3) BORDER-BASED BUTTONS</h4> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td bgcolor="#e9703e"> <a href="http://litmus.com" target="_blank" style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none; border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; background-color: #EB7035; border-top: 12px solid #EB7035; border-bottom: 12px solid #EB7035; border-right: 18px solid #EB7035; border-left: 18px solid #EB7035; display: inline-block;"><p style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none;line-height:30px;"> I am a button → </p></a> </td> </tr> </table> </td> </tr> </table> <!-- |||||||||||||||||| 4) PADDING + BORDER-BASED BUTTONS |||||||||||||||||| --> <h4 style="font-family:Arial;font-size:20px;line-height:22px;padding-top:10px;padding-bottom:10px">4) PADDING + BORDER-BASED BUTTONS</h4> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td align="center" style="-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px;" bgcolor="#e9703e"><a href="https://litmus.com" target="_blank" style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; padding: 12px 18px; border: 1px solid #e9703e; display: inline-block;"><p style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none;line-height:30px;"> I am a button → </p></a></td> </tr> </table> </td> </tr> </table> <!-- |||||||||||||||||| 5) LINE-HEIGHT BASED BUTTON |||||||||||||||||| --> <h4 style="font-family:Arial;font-size:20px;line-height:22px;padding-top:10px;padding-bottom:10px">5) LINE-HEIGHT BASED BUTTON</h4> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td bgcolor="#00c0e7" style="padding: 0px 0px 0px 0px; -webkit-border-radius:3px; border-radius:3px;" align="center"> <a href="http://edmdesigner.com" target="_blank" style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none;width: 150px; font-weight: normal; display: inline-block;"><p style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none;line-height:54px;"> I am a button → </p> </a> </td> </tr> </table> </td> </tr> </table> <!-- |||||||||||||||||| 6) NATIVE BUTTON in "a" TAG |||||||||||||||||| --> <h4 style="font-family:Arial;font-size:20px;line-height:22px;padding-top:10px;padding-bottom:10px">6) NATIVE BUTTON in "a" TAG </h4> <table cellpadding="0" cellspacing="0" border="0"> <tbody> <tr> <td valign="top" align="center"> <table cellpadding="0" cellspacing="0" border="0" bgcolor="#00c0e7" class="full-width" style="border: 1px solid #00c0e7; border-radius: 3px; border-collapse: separate !important; background-color: #00c0e7;"> <tbody> <tr> <td valign="top" align="center"> <a href="http://edmdesigner.com" target="_blank"> <button style="font-size:16px;font-family:sans-serif;background-color: #00c0e7;color:#ffffff;text-decoration:none;border-radius: 3px; border-radius: 3px; border:0px solid transparent;background-image: none;cursor: pointer;outline: none;"> <p style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none;line-height:54px;"> I am a button → </p> </button> </a> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <!-- |||||||||||||||||| 7) TABLE BASED BUTTON |||||||||||||||||| --> <h4 style="font-family:Arial;font-size:20px;line-height:22px;padding-top:10px;padding-bottom:10px">7) TABLE BASED BUTTON </h4> <table cellpadding="0" cellspacing="0" border="0"> <tbody> <tr> <td> <div> <a href="http://edmdesigner.com" target="_blank" style="text-decoration: none;"> <table cellpadding="0" cellspacing="0" border="0" bgcolor="#00c0e7" style="width: 160px;height: 54px; border-radius: 3px;"> <tbody> <tr> <td align="center"> <p style="font-size:16px;font-family:sans-serif;color:#ffffff;text-decoration:none;line-height:54px;"> I am a button → </p> </td> </tr> </tbody> </table> </a> </div> </td> </tr> </tbody> </table> </td> </tr> </table> <!--[if gte mso 9]></td></tr></table> <![endif]--> </center> </body> </html>

On Litmus, the bulletproof buttons we tested before - and even updated a little - behave as they did before. From the freshly introduced buttons, the line-height based button is worth special attention, it is covered in the next section in detail. We also had a "native button-based button", and a "table-based button" under investigation.

Native button-based buttons have shortcomings on some local webmails like GMX.de or Web.de - the outline:none property is not applied, as it is underlined the text in the previews. It also had the same display problems in Spark on Mac OS.

Table based buttons seem to work very well, but in the "click-through" test in the next section you will see this button-type fails without dignity.

You can check out the full source code of this step on Github.

Litmus test results

Click-through Test on Various Clients

We have nice looking buttons we can showcase now. It is just as important that they are clickable. So after the visual tests, it is necessary to click-test them in numerous clients. We need to be especially cautious with particular clients with HTML and CSS support imperfection.

The Test Scenario

The following table shows the client test I ran during this test suite. There may be an update later with the new client's tests and also you are free to suggest any other working or failing client test in the comment section below this article.

<caption>THE EMAIL CLIENTS TESTED</caption> <tr> <td> <table class="client-summary" width="100%" cellspacing="0" cellpadding="0"> <tbody> <!-- DESKTOP CLIENTS --> <tr> <td class="thead" colspan="3">Desktop clients</td> </tr> <tr > <td>Mac</td> <td>Windows</td> <td>Linux</td> </tr> <tr> <td> <ul> <p>Apple Mail</p> <p>Air Mail 3</p> <p>Spark</p> </ul> </td> <td> <ul> <p>Outlook 2007</p> <p>Windows 10 Mail</p> <p>eMail</p> </ul> </td> <td> <ul> <p>Thunderbird</p> <p>Geary</p> </ul> </td> </tr> </tbody> </table> </td> </tr> <tr> <td> <table class="client-summary" width="100%" cellspacing="0" cellpadding="0"> <tbody> <!-- MOBILE CLIENTS --> <tr> <td class="thead" colspan="3">Mobile clients</td> </tr> <tr> <td>Android 5.1</td> <td>iPhone</td> </tr> <tr> <td> <ul> <p>Inbox</p> <p>Gmail</p> <p>Yahoo! Mail</p> </ul> </td> <td> <ul> <p>Apple Mail</p> <p>Gmail App</p> </ul> </td> </tr> </tbody> </table> </td> </tr> <tr> <td> <table class="client-summary" width="100%" cellspacing="0" cellpadding="0"> <tbody> <!-- WEBMAIL CLIENTS --> <tr> <td class="thead" colspan="3">Webmail clients</td> </tr> <tr> <td>Chrome</td> <td>Firefox</td> <td>Internet explorer</td> </tr> <tr> <td colspan="3"> <ul> <p>Yahoo! Mail</p> <p>Gmail</p> <p>Outlook.com</p> <p>Mail.ru</p> <p>AOL Mail</p> </ul> </td> </tr> </tbody> </table> </td> </tr>

The Problem with Padding-based Buttons

An email coder will sooner or later encounter: on padding-based buttons only the link is clickable. The following animation shows, that only the link can be clicked:

Although it is known, as one of the most stable button across legacy email clients, it has poor user experience. Because only the link is clickable, the users must click or tap very precisely on their desktop and mobile devices. This behavior is the result of the padding property, which increases the space around the link, without making it clickable. Considering this drawback and the option for better alternatives, you may move on to use other button types.

Table Based Buttons are not Always Clickable

This technique seemed promising in the visual tests, but if you try to click it ...

...on Outlook 2007 ...

... or Windows 10 Mail ...

... you can see it fails. You may notice, that the link does not convert the pointer to the little hand, as it does above with the other button types. I also clicked on it several times, but nothing happened. This means that the table-based button type is good, but not bulletproof. It does not support several desktop Outlook versions. The good news is, that all the other buttons survive our test even on legacy clients.

The New Line-height Based Bulletproof Button

The essence of this new approach is to apply the previously discovered fixes on the button. We use the a tag with display: inline-block as the button, as all the different approaches. We can set the width with inline style, as the VML-based button does, which proved to be clickable on all clients.

The button component in the end looks like this:

<table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td bgcolor="### COLOR ####" style="#### STYLES ####; -webkit-border-radius:3px; border-radius:3px;" align="center"> <a href="### HREF ###" target="_blank" style="### FONT PROPERTIES ###;text-decoration:none; line-height:54px; width: 150px; display: inline-block;"> <p style="### FONT PROPERTIES ###; line-height:54px;"> I am a button → </p> </a> </td> </tr> </table> </td> </tr> </table>

In contrast with the padding-based button, we apply the height property by setting line-height in inline style, as padding is not supported on a elements in Outlooks. Also it is worth to note, that line-height is a really well supported CSS property. You can look it up on Campaign Monitor or MDN. We set the bgcolor attribute of the wrapping table's td tag, to support Lotus Notes versions too. We also need to wrap the button's text in a p tag, on which we need to apply styles for correct display. The line-height based button proved to work in all email clients I tried so far. The button can be clicked on the whole background area.

Our example is minimal art, but you can style it according to your taste. Feel free to use his button everywhere you like! Keep in mind to use the core design principles for the next generation of bulletproof buttons (5th in the example preview).

You can check out the full source code of this step on Github.

Litmus test results

Summary

In this article you could revisit the various bulletproof button types by Litmus, and see how they perform on the visual tests. With some slick updates on these methods, we could extend their use cases, so they support legacy desktop clients.

By the new properties a new bulletproof button concept was born: the Line-height based button. It is constructed by tailoring button dimensions with line-height and width properties on the a tag.

I ran a "click-through" test on various clients, on multiple devices. My test results showed, that the introduced new button, and the basic buttons upgraded with the highlighted properties are fully clickable (except padding-based) and well supported.

Though I did not encounter incompatibilities in my tests, there may be upcoming issues, as the test is far from being complete. It still needs to be tested on many devices with different environments.

If you come across any drawbacks with the line-height based approach, please share it in the comment section below!

Our next post will teach you about background-images. Join us next time as well!