Emails with Haml and Jekyll Front Matter

in Front-end

I recently shared the planning and organization behind emails at Code School, so now it’s time to get into the more technical bits of how they are created.

Base styles

The core styles set up for Emayll are intended to look “wireframey” (not a word but it should be). There is a full description of all of the variables in the repo, but I’ll explain them in context. There are 3 files, with some intentional repetition of styles between them, so I’ll walk you through the changes that I made to customize these for Code School.

image

Global Patterns

The settings in the front matter will change as we go, but the content patterns are the primary ones that are used in Code School emails. Text headers and links are referenced here to maintain consistency throughout messages.

Nearly all layouts that are created for Code School come from 3 patterns: basic content, content with a colored background, and split content.

In addition to having these for reference in a file, I recently created them as Atom snippets. Of all the workflow things I’ve done, this is my favorite.

Check out how easy it is to add a button with a snippet:

image

For Code School emails, we design standard messages that look similar to the site. Here is a breakdown of each section.

image

Header

For most of our emails we use a header with just the logo, but we also use preview text in some.

Standard Header

%table{ bgcolor: "{{ page.hdr-c-bg }}", style: "{{ page.hdr-border }}", width: "100%", {{ page.tbl-base }} }
  %tr
    %td

      %table.flex-size{ align: "center", style: "color: {{ page.hdr-c-base }}; {{ page.tbl-typeset }}", width: "600", {{ page.tbl-base }} }
        %tr
          %td.s-height{ colspan: "3", height: "15" }

        %tr
          %td{ width: "{{ page.gutter }}" }

          %td{ align: "center" }
            %a{href: "http://codeschool.com/", style: "display: block; width: 150px;"}
              %img.cs-logo{alt: "Code School - Learn by doing", src: "http://d367zuf2xzw0m3.cloudfront.net/common/codeschool-logo.png", width: "150"}/

          %td{ width: "{{ page.gutter }}" }

        %tr
          %td.s-height{ colspan: "3", height: "20" }

Header with pretext

%table{ bgcolor: "{{ page.hdr-c-bg }}", style: "{{ page.hdr-border }}", width: "100%", {{ page.tbl-base }} }
  %tr
    %td

      %table.flex-size{ align: "center", style: "color: {{ page.hdr-c-base }}; {{ page.tbl-typeset }}", width: "600", {{ page.tbl-base }} }
        %tr
          %td.s-height{ colspan: "3", height: "15" }

        %tr
          %td{ width: "{{ page.gutter }}" }
          %td

            %table.flex-size{ align: "left", width: "150", {{ page.tbl-base }} }
              %tr
                %td{ align: "center" }

                  %a.s-tac{ href: "http://codeschool.com/", style: "display: block; width: 150px;" }
                    %img.cs-logo{ alt: "Code School - Learn by doing", src: "http://d367zuf2xzw0m3.cloudfront.net/common/codeschool-logo.png", width: "150" }/

                  %table.flex-size{ align: "right", width: "350", {{ page.tbl-base }} }
                    %tr
                      %td.s-pts{ style: "color: #999999; font-size: 10px;", "mc:edit" => "pretext" }

                        "We use this area to offer a short teaser of your emails content. Text here will show in the preview area of some email clients."

          %td{ width: "{{ page.gutter }}" }

        %tr
          %td.s-height{ colspan: "3", height: "20" }

Using the calls for the front matter allows them to be updated quickly. If I want to fully theme out an email, I can just make changes in that file to override the colors. If I was sure that these would change in the event of a complete brand redesign, they could be pulled from templates and hardcoded into the layout.

hdr-c-base: "#37a381"
hdr-c-bg: "#ffffff"
hdr-c-link: "#0b684d"
hdr-border: "border-bottom: 1px solid #f5f5f5;"

Footer

The footer is similar. It contains MailChimp-specific items, as well as some social links.

%table{ bgcolor: "{{ page.ftr-c-bg }}", style: "{{ page.ftr-border }}", width: "100%", {{ page.table-base }} }

  %tr
    %td{ height: "5" }

      %tr
        %td

          %table.flex-size{ align: "center", style: "color: {{ page.ftr-c-base }}; {{ page.tbl-typeset }} font-size: 12px;", width: "600", {{ page.table-base }} }
            %tr

             %td{ width: "{{ page.gutter }}" }

             %td{ align: "center" }
               %a{ href: "http://twitter.com/codeschool/{{ page.tracker}}", style: "color: {{ page.ftr-c-bg }}" }
                 %img{alt: "Twitter Icon", height: "24", src: "http://d367zuf2xzw0m3.cloudfront.net/common/social-twitter.png", width: "24"}/

               %a{ href: "http://facebook.com/codeschool/{{ page.tracker }}", style: "color: {{ page.ftr-c-bg }}" }
                 %img{alt: "Facebook Icon", height: "24", src: "http://d367zuf2xzw0m3.cloudfront.net/common/social-facebook.png", width: "24"}/

               %a{ href: "http://www.youtube.com/user/CodeSchoolTV/{{ page.tracker }}", style: "color: {{ page.ftr-c-bg }}" }
                 %img{alt: "Youtube Icon", height: "24", src: "https://gallery.mailchimp.com/8234ed62d6a7fa87721ff1d8a/images/email_social_youtube.png", width: "24"}/

               %a{ href: "https://plus.google.com/104172014188858296563/posts/{{ page.tracker }}", style: "color: {{ page.ftr-c-bg }}" }
                 %img{alt: "Google+ Icon", height: "24", src: "https://gallery.mailchimp.com/8234ed62d6a7fa87721ff1d8a/images/email_social_gplus.png", width: "24"}/

              %td{ width: "{{ page.gutter }}" }

                %table.flex-size{ align: "center", style: "color: {{ page.ftr-c-base }}; {{ page.tbl-typeset }} font-size: 12px;", width: "600", {{ page.table-base }} }

                  %tr
                    %td{ colspan: "3", height: "5" }

                  %tr
                    %td{ width: "{{ page.gutter }}" }
                    %td{ align: "center" }

                      Have questions or need assistance?
                      %br
                      %a{ href: "http://help.codeschool.com/{{ page.tracker }}", style: "color: {{ page.ftr-c-link }}" } help.codeschool.com

                    %td{ width: "{{ page.gutter }}" }

                  %tr
                    %td{ colspan: "3", height: "5" }

                  %tr
                    %td{ width: "{{ page.gutter }}" }
                    %td{ align: "center" }

                      %a{ href: "https://www.codeschool.com/account/edit/{{ page.tracker }}", style: "color: {{ page.ftr-c-link }}" } Edit your email settings

                      %a{ href: "*|UNSUB|*", style: "color: {{ page.ftr-c-link }}" }
                      Unsubscribe

                    %td{ width: "{{ page.gutter }}" }

                  %tr
                    %td{ colspan: "3", height: "5" }

                  %tr
                    %td{ width: "{{ page.gutter }}" }
                    %td{ align: "center", style: "font-size: 10px;" }

                      Our mailing address is:
                      618 E South Street • Suite 620, Orlando, FL 32801

                    %td{ width: "{{ page.gutter }}" }

                  %tr
                    %td{ colspan: "3", height: "5" }

                  %tr
                    %td{ width: "{{ page.gutter }}" }
                    %td{ align: "center", style: "font-size: 10px;" }

                      %em Copyright © Code School LLC, All rights reserved.

                    %td{ width: "{{ page.gutter }}" }

                  %tr
                    %td{ height: "5" }

It can also be customized per email, with the front matter.

ftr-c-base: "#dcdbd2"
ftr-c-bg: "#535456"
ftr-c-link: "#f7f7f7"
ftr-border: "border-top: 1px solid #f5f5f5;"

Body

There are some things that have to be repeated on every table: border, cellpadding, cellspacing. Any table containing text also needs the font styles set. These can be reduced a little bit with the front matter, which helps tidy up the code overall.

tbl-base: "border: '0', cellpadding: '0', cellspacing: '0'"
tbl-typeset: "font-family: 'Open Sans', AppleSDGothicNeo-Medium, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.4;"

Setting the base colors for background, type, and links allows for quick customization of the message look.

c-bg: "#f7f7f7"
c-base: "#252525"
c-link: "#228b9b"
c-title: "#3f4944"

Gutter was introduced to my Code School workflow as a direct response to Mailbox app’s rendering on iOS. It makes the outermost table 100%, which allows text to run into the edges. This also happens if you resize a browser small enough when using Gmail. This way, I will always have an ‘x’ pixel gap on the edges. gutter: "20"

Button

The default button colors are set with variables too.

btn-c-base: "#ffffff"
btn-c-bg: "#228b9b"
btn-c-shadow: "#196671"

A table

This is a standard table that is used for content, ready for customization.

%table.flex-size{ style: "color: {{ page.c-base }}; {{ page.tbl-typeset }}", width: "600", {{ page.tbl-base}} }

 %tr
   %td{ colspan: "3", height: "25" }

 %tr
   %td{ width: "{{ page.gutter }}" }
   %td{ align: "left" }

     %h1{ style: "margin: 0; padding-bottom: 5px;" } This is a thing that exists

     Here is some information about it.

   %td{ width: "{{ page.gutter }}" }

 %tr
   %td{ colspan: "3", height: "25" }

Styles

The reason that I have yet to add automated inlining to my workflow is that I mostly rely on front matter for this. However, it is necessary to have styles in media queries. The primary purpose of the CSS is for forcing the tables to be fluid, but there are a few helper classes added in to adjust sizing and spacing. This is one area where I rely on padding because the clients that support media queries typically handle padding well.

GG@media (max-width: 320px) {

  /* Forces the button to full width */

  .btn-full {
   width: 100% !important;
  }

}

@media (max-width: 600px) {

  /* Typography */

  table {
   font-size: 14px !important;
  }

  h1 {
   font-size: 20px !important;
  }

  h2 {
   font-size: 18px !important;
  }

  h3 {
   font-size: 16px !important; }

  h4 {
   font-size: 14px !important; }

  h5 {
   font-size: 14px !important;
  }

  /* Reduces the brand size on small resolutions */

  .cs-logo {
   width: 120px !important;
  }

  /* Makes fixed width items flexible */

  .flex-size {
   width: 100% !important;
  }

  /* Contains content images */

  .flex-size img {
   max-width: 100% !important;
  }

  .s-height {
   height: 10px !important;
  }

  .s-pts {
   padding-top: 8px !important;
  }

  .s-tac {
   text-align: center !important;
  }

  .s-tal {
   text-align: left !important;
  }

}

Your Turn

This is all available in a Github repo if you would like to get started using Haml and Jekyll for your HTML emails. If you have a system of your own, I’d love to check it out. Shoot me a link on the Twitters, @dandenney.

Code School

Code School teaches web technologies in the comfort of your browser with video lessons, coding challenges, and screencasts. We strive to help you learn by doing.

Visit codeschool.com

About the Author

Dan Denney

I’m a seriously good copy and paster. Front-end dev for @codeschool, lover of all things web design/dev related and founder of @frontendconf.

Might We Suggest