Mastering Email with Ruby

F4612f9492cccc0c61c9b5f80d0ca8a1?s=47 jng
October 08, 2015

Mastering Email with Ruby

E-Mail persists after many decades and will also survive the next hyped communication technology. Despite being a pest, E-Mail is also an effective marketing channel and one of the most personal communications you have with your users and customers. 

Responsive E-Mail HTML is not as difficult as many think. We'll look at some common problems with solutions for developing bulletproof E-Mails. But most importantly we'll look at how programming workflow is just as important and how I use Ruby to do that.

---

Notes: This online PDF has a few more slides than the presented version, to explain a screenshot or some code.

F4612f9492cccc0c61c9b5f80d0ca8a1?s=128

jng

October 08, 2015
Tweet

Transcript

  1. 2.

    Julie Ng • American Developer in Munich • Previously Designer

    at ancestry.com for European Markets • UX Email Developer, Consultant • Refresh Munich e.V. Chairwoman • Runner, Climber
  2. 4.

    1. More Code 
 required to create bulletproof emails 2.

    Extra Build Step
 inline css - thanks Google! 3. Manage shared code? 
 no best practice conventions when shared CSS Email is tedious
  3. 5.

    Email Cut Offs Source: Neil Bursnoll, Adestra adestra.com/avoid-gmail-clipping-emails Source: Geoff

    Phillips, Email on Acid emailonacid.com 102 kb Gmail Web Source: Ros Hodgekiss, Campaign Monitor campaignmonitor.com 20 kb Gmail iOS 15 kb Mail iOS
  4. 7.

    Image <img src="<%= source %>" border="0" alt="<%= alt %>" <%=

    " width=\"#{width}\"" if defined? width %> <%= " height=\"#{height}\"" if defined? height %> <%= " align=\"#{align}\"" if defined? align %> <%= " styles=\"#{styles}\"" if defined? styles %> <%= " class=\"#{klass}\"" if defined? klass %> hspace="0" vspace="0" > *required for Outlook
  5. 9.

    Button <table border="0" cellspacing="0" cellpadding="0" class="button yellow" align="center"> <tr> <td

    align="center"><a href="http://juile.io/"><!--[if mso]>&nbsp;<![endif]-->A button →<!--[if mso]>&nbsp;<![endif]-- ></a></td> </tr> </table> Note: no whitespace in code between <td></td> for Outlook
  6. 10.

    Button (inlined) <table border="0" cellspacing="0" cellpadding="0" class="button yellow" align="center" style="margin-left:auto;margin-

    right:auto"> <tr> <td align="center" style="-webkit-border-radius:3px;-moz- border-radius:3px;border-radius:3px;background- color:#2095F2;background-color:#f1c40f;border- color:#dab10d;color:#6F4F1D"><a href="http://juile.io/" style="-webkit-border-radius:3px;-moz-border-radius:3px;border- radius:3px;font-weight:bold;font-size:14px;line-height: 20px;font-family:Helvetica, Arial, sans-serif;text- decoration:none;display:inline-block;padding:12px 18px;border: 1px solid #0e89eb;background-color:#2095F2;background- color:#f1c40f;border-color:#dab10d;color:#6F4F1D"><!--[if mso]>&nbsp;<![endif]-->A button →<!--[if mso]>&nbsp;<![endif]-- ></a></td> </tr> </table>
  7. 12.

    Grid with <table>s <!--[if mso]><table><tr><td width="300"><![endif]--> <table align="left" width="100%" style="max-width:300px">

    … Column 1 … </table> <!--[if mso]></td><td width="300"><![endif]--> <table align="left" width="100%" style="max-width:300px"> … Column 2 … </table> <!--[if mso]></td></tr></table><![endif]-->
  8. 13.

    You can use <th> instead of <td> Can use display:block!

    on <th> for responsive layouts. But seems wrong to me.
 You can use Margin:5px; instead of margin:5px; But then beware of CSS inliners (more later) Bulletproof = NO hacks
  9. 14.

    Defensive Coding <table style="font-family:Helvetica;"> <tr> <td> this will not be

    in Helvetica :( </td> </tr> <tr> <td style="font-family:Helvetica;"> but this will :) </td> </tr> <tr> <td style="font-family:Helvetica;"> I will be Helvetica <img> Me too. But I might be purple in Gmail. </td> </tr> </table>
  10. 15.
  11. 19.

    1. Inlined CSS
 (Thank you Gmail) 2. Included CSS CSS

    Resets Desktop resets (e.g. grids) Media Queries for responsive layouts 2 Layers of CSS Same, same, but different is hard
  12. 20.

    CSS Inliners Compared Styliner Juice Premailer Roadie Language JavaScript JavaScript

    Ruby Ruby GitHub Favorites 91 895 1466 865 GitHub Issues 6 10 93 4 Affects Markup? ? sometimes… sometimes… Nokogiri… Shorthand CSS? ? Yes Yes No Respects HTML Comments? ? ? ? Yes Respects <style>? ? Supposed to Yes Sometimes? Check issues. Try it. Stats from September 2015
  13. 21.

    Not all CSS is inlined <style> /* Do not inline!

    iOS autolinks */ .ios-footer a { color: #999999 !important; } </style> <span class="ios-footer"> MyCompany.com 123 Main St Springfield, MA </span>
  14. 24.

    No shorthand CSS .example { /* This works across all

    clients */ background-color: #ff0000; background-image: linear-gradient(#111111, #222222 50%, #111111); /* But the same as shorthand does not because Outlook does not understand linear-gradient, so ignores all values for background. */ background: #ff0000 linear-gradient(#111111, #222222 50%, #111111); }
  15. 25.

    Do not change or adjust HTML Preserve comments (esp. if

    mso) Do not use CSS shorthand Inline some styles, but not others. Include some styles, but not others. CSS Inliner Checklist
  16. 28.

    Templates, support for partials Development preview Inlines CSS (Premailer) Missing:

    options for individual stylesheets build partials preserve logic grunt-email-workflow grunt-email-workflow github.com/leemunroe/grunt-email-workflow
  17. 29.

    Can use Front Matter for custom stylesheets Has useful content_for

    helper Has Live Preview Missing: inlined CSS build partials preserve logic Middleman Middleman middlemanapp.com
  18. 30.

    Why Partials? <table> <tr> <td class="t-1st">Item</td> <td>Qty</td> <td class="t-last">Subtotal</td> </tr>

    <% @config.products.each do |product| %> <%= partial :product, locals: product %> <% end %> </table> <tr class="prod"> <td class="p-img t-1st"><%= image_tag url %></td> <td><%= title %></td> <td><%= quantity %></td> <td class="p-eur t-last"><%= price %></td> </tr> TEMPLATE PARTIAL
  19. 31.

    emails are more than just newsletters. have re-usable components. we

    can easily port inlined partials with preserved logic into any backend framework you use. 
 Conclusion 
 Just because email is more tedious, it doesn't mean we can't apply general development best practices. Partials because…
  20. 33.

    1. Development 2. Upload Images 3. Inline CSS 4. Send

    Email 5. Test/Debug 6. Rinse and Repeat Workflow
  21. 37.
  22. 38.
  23. 40.
  24. 42.
  25. 43.
  26. 44.

    1. Development: sinatra, sass, rack-livereload 2. Upload Images: fog, aws

    3. Inline CSS / Build HTML: roadie, Regular Expressions 4. Send Email: mail 5. Test/Debug 6. Rinse and Repeat Workflow