What’s in an email?

kellycodeschaos profile image Kelly Harrop Originally published at Medium on ・8 min read

Crafting an Email Design System

When creating an email campaign, using a component-based system is crucial for delivering a quality experience to your audience as quickly and efficiently as possible.

Photo by Web Hosting on Unsplash

Unfortunately, designing and developing for email can be challenging due to the limitations of email clients and inconsistencies across browsers and platforms. Most of the wonderful flexibilities of the modern-day web are unavailable when coding for email due to what is supported.

That being said, let’s explore how we can create a system that’s both easy to configure and implement!

Photo by NordWood Themes on Unsplash

Branding Baseline

It’s important to establish what is critical to your brand’s baseline. At minimum, this is typically assigning a color palette and potentially custom fonts.

Remember that all the quirks that come with your brand don’t need to be reflected in your email campaign!

Here’s a quick example of how you could structure color and typography as variables in a scss file used in your template:

/***** COLORS ******/

/* raw values -- do NOT reference */
$blue01: #0000ff;

/* role -- reference these */
$primary: $blue01;

/***** TYPOGRAPHY ******/

@function calculateRem($size) {
 $remSize: $size / 16px;
 @return #{$remSize}rem;

@mixin fontSize($size) {
 font-size: $size; //Fallback in px
 font-size: calculateRem($size);

H1 {
color: $primary;
@include fontSize(32px);

I like this approach because you can easily update the value of your $primary variable if you need to. If you’re wondering why I don’t just assign a HEX value to $primary, I can technically do that — but then it’s easy to forget what I’m really referencing since that raw value isn’t very descriptive.


I start with typography because when you have a strong hierarchy of information, the content of your email will shine regardless of what colors you choose.

Photo by J-S Romeo on Unsplash

But what happens if you want to use your custom brand font? Custom fonts can be a little tricky depending on their source because they can render incorrectly for certain combinations of platform and email client. I would highly recommend finding a similar Google Font if possible as they are more reliable and already hosted. Will anyone even notice?

When deciding what you want to include in your template, start off with the basics:

  • Headers (H1, H2, H3…)
  • Body text (p)
  • Links (a)
  • Buttons (a)


Let’s say your brand already has a base color palette referenced in your product/website. Awesome! Because emails contain static images and text, you don’t need to import all of them. Try to keep it simple with one or two main brand colors for the interactive parts of your email (links and buttons).

Photo by Kaleidico on Unsplash

Setting up the structure

Now that you have branding covered, the next step is establishing what actually goes in your template.


Components are important because they determine what parts of your system are reusable and referenced. Like a regular design system, you’ll need to determine what parts should stay as small as possible.

Let’s look at some common email components and options to consider:

  • Headers: Text alignment, margin, typography, color
  • Body text: Text alignment, margin, typography, color
  • Buttons: Alignment, sizes, typography, color
  • Dividers: Full width, small width, color
  • Images: Sizes

Using these components, you can create pre-configured compound components (the molecules of atomic design) so you don’t have to manually include the same set of components every time you need a group of them.

Sample molecules:

  • Molecule: Header + body text
  • Molecule: Image + body text

And last but not least, I like to have my organisms create the “sections” of my email:

  • Section: Intro (image + header + text + optional button)
  • Section: Three column grid (images and text in three columns for desktop)
  • Section: Avatar bio (small image + header + body text)

More about sections

Sections deserves its own callout because it’s such an integral part of your email template. These sections define what is available for use when thinking about the content you’re creating. Any time you deviate from a section, you’re creating “snowflake” code and designs, which defeats the purpose of having a system.

In order to be a successful email template, define what kind of content you are sharing with your audience. Is it promotional? A newsletter? An update to your privacy policy? Whatever it is, you should be clear about what kind of content sections need to be supported.

Once you have your sections, the next crucial part is socialization. If you are working with a team who will be creating emails using your template, they need to know what these sections are called. For example, you may get questions like:

  • How do I create cards?
  • How do I position an image to the left of text?
  • How do I insert a footer?

Or worse, they’ll just create their one-off section type and not use what was already created! Having a consistent naming convention and making sure that it’s obvious what to use both in design (as symbols) and in code (as commented code blocks) will help your team work faster by using the same terms.

Layout for tables

Yes, it’s 2019 (as of this article) and we’re still having to rely on tables for our email. That’s okay though, because that just means we have to be deliberate about our table cell structure.

When designing your content, you’ll need to think in terms of left or right alignment and how your tables interact with each other. By nesting tables within tables, you can set rules for how content flows together.

Personally, I prefer starting out with a desktop layout before mobile. The reason being, your sections will typically just go full width and be stacked in mobile, which is fairly straight forward. Desktop is where some of the planning and table layouts become a challenge. It’s easier to convert a multi-nested table to a series of stacked tables than the other way around.

Here’s a simplified example of how I implemented a section block (“Intro paragraph”) using Salesforce’s Pardot email system:

As you can see, you can create these modular section blocks using a bunch of nested tables and then use a GUI platform to configure and assemble your specific email.

The biggest thing to note is that you must use nested tables in order to properly align your content.

Also note that I’m not putting in a bunch of HTML attributes because I can handle that part later (more in the Workflow section!).


Once you’re finished with your desktop layout template, converting that to a responsive view is simply a matter of stacking the content in each section vertically instead of side by side.

To do this, I just add a class to sections that I want to stack as “mobile-100” and then include a media-query that overrides my styles to make any HTML tag with that class go full-width and stack on top of each other.

It’s a quick way for me to understand that this class is mobile-specific and the 100 lets me know that the content will go 100% width of the parent. Easy!

Automate your workflow

Congratulations, you’re almost done! At this point, you should have designs and coded system in place that covers:

  • Branding: Typography & Colors
  • Structure: Components, Layout (desktop + mobile)

Photo by Glenn Carstens-Peters on Unsplash

Back in the day, you’d have to make sure all these elements worked in different browsers and platforms by manually inserting inline-styles and HTML attributes.


Well, I’m happy to say that this is no longer the case since you can leverage Javascript to automate these tasks for you!


Gulp is just a fancy tool that runs tasks for you so you don’t have to manually type everything. Nifty, right? You write your tasks in a Javascript file and then run a single command in terminal. The benefit of this is both having having easy-to-read and manageable HTML files as well as not worrying about missing an attribute.

Get started with Gulp : https://gulpjs.com/docs/en/getting-started/quick-start

Once you have gulp set up, create a gulpfile.js file in your root directory.

In my Gulpfile.js, I have multiple functions:

  • A function that watches my scss file and exports that as a css file
  • A function that looks at my new css file and injects that as inline styles to my HTML template file
  • A function that looks at any <table> in my HTML file and inserts cellspacing, cellpadding and border-collapse attributes

Then at the bottom, I make sure that my tasks are watching the files that they should be referencing and run a command in terminal (“gulp”) when I need to do any work on this template.

Running these tasks also generates a new HTML file (“pardot-email.html”) in a different folder (“build”), so I easily know the difference between my working file and the file that gets built at the end. When I’m ready to test out what this email looks like locally, I can open the newly built HTML file in my browser to double check that everything looks okay.

Now it’s just a matter of picking a section that serves your content best and modifying the text in either code or in whatever GUI you are using (Pardot, Mailchimp, etc).

Photo by Austin Distel on Unsplash


  • “!important” is actually… important. Even though in the modern web world it’s frowned upon, they are a necessary evil in email templates due to how email clients want to override everything
  • MS Outlook renders emails as Word documents, which means sometimes your longer emails will come with an unfortunate vertical gap. You can read more about it here. I’ve solved this in the past by having an additional <tr> wrap the content.
  • Litmus tests can lie occasionally with font rendering. Try to test it in the actual email client/platform if available when you suspect something should be working.
  • Browsers and email clients are very finicky with margin and padding, in that some don’t support margin at all. If you need the extra spacing, padding is pretty consistent for ’s (make sure you have content in there!) like:
<td class="spacer-20">&nbsp;</td>

// spacer-20 has padding:20px assigned
// " " renders as a space

Thank you!

Any follow up questions? Feel free to ping me on Twitter @kellycodeschaos !

Additional helpful articles

Posted on by:

kellycodeschaos profile

Kelly Harrop


I’m a product designer specialized in frontend tech with bonus experience in visual design and design systems.


markdown guide