We all know email development can be a pain in the @#$%. Heck, sometimes you can take this phrase even literally: I mean who hasn’t pulled out a few hairs over some weird outlook bugs.

Seeing as most front-end developers’ main focus does not lie in email development - yes there are dedicated email developers, bless them - the email development process may seem a tad tedious, if not repetitive. It may even feel like a journey back to a time where layouts based on nested tables were considered best practice. "Well hello 1999, how've you been doing, it has been a while?".

The problem

For those of you who don't know what we're dealing with and why the development of an email isn't always welcomed with open arms, consider this small example. Say you have to make a button. An orange button with rounded corners, to be precise.

Reproducing this in a website is rather straightforward, create a <button></button> tag, insert your CTA, and style this element in your linked stylesheet like this:

button {
	display: block;
	padding: 0 12px;
	
	color: $button-color;
	font: {
		family: Arial, Helvetica, sans-serif;
		size: 18px;
	}

	background-color: $button-bg;

	border-radius: 10px;
}

that's it, you can even be smart and add a class to the button element so you can reuse the styling everywhere you want => code once, use everywhere you need.

Now if you want to do this in an email you're code will look like this:

<table cellpadding="0" cellspacing="0" border="0">
    <!-- button-top -->
        <tr>
            <td valign="top" align="left">
                <img alt="" src="img/btn-orange-topleft.png" style="border:none; display:block;" />
            </td>
            <td valign="top" align="left" style="background-color:#f16529;">
                <img src="img/spacer.gif" width="20" style="border:none; display:block;">
            </td>
            <td valign="top" align="left">
                <img alt="" src="img/btn-orange-topright.png" style="border:none; display:block;" />
            </td>
        </tr><!-- /button-top -->
        <!-- button-middle -->
        <tr>
            <td valign="middle" align="left" style="background-color:#f16529;">
                <img src="img/spacer.gif" width="10" style="border:none; display:block;">
            </td>
            <td valign="middle" align="left" style="background-color:#f16529;">
                <table cellpadding="0" cellspacing="0" border="0">
                    <tr>
                        <td valign="middle" align="left" style="background-color:#f16529; font-family:Arial,Helvetica,sans-serif; color:#FFFFFF; font-size:18px; line-height:20px; padding: 0 10px;">
                            <a href="#" target="_blank" style="color:#FFFFFF; text-decoration:none; background-color:#f16529;">Download de brochure</a>
                        </td>
                        <td valign="middle" align="left" style="background-color:#f16529; padding-right:10px;">
                            <a href="#" target="_blank">
                                <img src="img/pijltje.png" style="display:block; border:none;">
                            </a>
                        </td>
                    </tr>
                </table>
            </td>
            <td valign="middle" align="left" style="background-color:#f16529;">
                <img src="img/spacer.gif" width="10" style="border:none; display:block;">
            </td>
        </tr><!-- /button-middle -->
        <!-- button-bottom -->
        <tr>
            <td valign="top" align="left">
                <img alt="" src="img/btn-orange-bottomleft.png" style="border:none; display:block;" />
            </td>
            <td valign="top" align="left" style="background-color:#f16529;">
                <img src="img/spacer.gif" width="20" style="border:none; display:block;">
            </td>
            <td valign="top" align="left">
                <img alt="" src="img/btn-orange-bottomright.png" style="border:none; display:block;" />
            </td>
        </tr><!-- /button-bottom -->
</table>

All of this for just one button. Because you can't use external stylesheets (hence the inline styling), you can't use semantic html elements: you're stuck with tables instead, padding and margins don't always behave nicely, which implies the use of spacer .gif(s), ... the list goes on and this only for one button. With dozens of lines of html code for one single button, it's not hard to imagine how the source code of a whole mail will look.

Saying it's kind of a mess can be an understatement. Quick copy fixes, changing the href attribute of one link, ... it all requires some searching, which is fine if the file has proper indentation, if that's not the case: good luck and try to stay calm. The main reason why all of this is necessary, why we're dealing with obsolete code, is Microsoft Outlook. Some time ago, someone had the brilliant idea of rendering web based content (the mail) with a text processor (Microsoft Word) instead of an actual browser designed to render web based content (Internet Explorer), granted that browser had quirks of it's own, but still. Further details can be found here.

Lightening the burden

So can we do something about this, can we lighten the burden? Well, the good news is that there is a lot of open source tooling and automatisation available, you can find tools that inline your styles, test your mails, there's even a templating language which prevents you from writing endless tables and makes it a lot more easy to keep an overview. So if there are a lot of options regarding speeding up email development, why add another one? Well, here at Kunstmaan we've used all kinds of different tools in our process, but every time there seemed to be something lacking. There wasn't something that provided all functionality we wanted in the way we wanted. And that’s why we created Orbit.

Orbit, at it's base, is a boilerplate based on gulp and inspired by the foundation-emails-template from the lovely people at Foundation, who also happened to create the Inky templating language. It combines all the functionality we liked about other open source options with some features of our own. Let's take a look at what's included in the package:

HTML

Bloated HTML files for emails are a thing from the past, we've implemented the twigjs templating language in orbit to enable us to divide our html into bitesize chunks of code, this improves legibility and makes small adjustments a lot less tedious. To further enhance legibility, Orbit also includes the Inky templating language this helps to minimise the amount of tables you have to write, i.e.: remember the orange button? With Inky you can just add a <button> element and our build task will generate all the required tables.

Styling

One of the biggest pains in developing emails was the endless copy pasting of styling of the same components, reusability is an unknown concept in email development. With Orbit you can just write SCSS like you normally would, add a class to a component, hook up styling and Orbit will take care of inlining it in the HTML when required, it also combines all mediaqueries in your scss files and injects them into the head of your html.

Images

Another annoying, repetitive task we've come across related to images, to be more precise the location of the images used in an email. Presume you just finished writing your email code and want to test the whole thing, so sending it to litmus is the task at hand. This implies that all used images need to be hosted somewhere, not a problem just upload them to a ftp server, however changing the src attributes of all images from a local path to path on the server, and back gets very annoying after you've done it a couple of times. Orbit does this for you with the {{ asset() }} function, just pop in the filename and the path to the image will change depending on which task you run.

Translations

All content inside your mail is located in .yaml files. Searching through hundreds of lines of html code to change one sentence is a thing from the past. You're welcome.

Testing

We've integrated Litmus testing in Orbit. Just specify your credentials in the main config.json file and you're set to go. You can also send test emails to specific email addresses which will come in handy when your client wants to see the email.

Available commands

npm run start

Is the default development task. It'll compile the SCSS files, build the Twig templates, minify images and start up a local development server.

Note: the {{ asset }} function will set the base path for images to a local ./dist/img/

npm run build

Does everything the start command does but won't start a local server. It'll inline your styles into your html instead.

Note: by default Orbit creates an html file for each translation file located in the translations directory. You can build a specific version by running the build task with a language flag i.e: npm run build -- --lang nl

npm run zip

Runs the build task and generates a zip package of all built html files and images.

npm run test

This builds your emails, deploys all images to a specified ftp server, sets the image base path to that location and sends a test to litmus using the credentials from the config.json file located in the root of your project.

npm run mail

Builds the mail and sends a test version to a specified email address.

Great but now what?

As you can see in our to do-list, there are still some items to be sorted out. Also we see this as een evolving project and we'd love some community support, so if you're interested in this project and would like to help us out improving it, submit issues on our issue list or even better submit a pull request.

Written by

Kevin Fivé

Frontend developer

Follow @_fvkvn