Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mastering Email with Ruby

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.

jng

October 08, 2015
Tweet

More Decks by jng

Other Decks in Programming

Transcript

  1. Mastering Email with Ruby
    Julie Ng
    RubySauna

    Helsinki, Finland
    8 October 2015

    View Slide

  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

    View Slide

  3. Email != hard

    View Slide

  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

    View Slide

  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

    View Slide

  6. Email = more HTML

    View Slide

  7. Image
    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

    View Slide

  8. Bulletproof = more code
    and

    View Slide

  9. Button


    A button →

    View Slide

  10. Button (inlined)


    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">A button →

    View Slide

  11. Tables for Layouts

    View Slide

  12. Grid with s


    … Column 1 …



    … Column 2 …


    View Slide

  13. You can use instead of
    Can use display:block! on 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

    View Slide

  14. Defensive Coding



    this will not be in Helvetica :(




    but this will :)




    I will be Helvetica

    Me too. But I might be purple in Gmail.



    View Slide

  15. View Slide

  16. Tedious Builds

    View Slide

  17. Compile CSS
    Concatenate HTML
    Upload images
    Build
    OK, it's not that hard…

    View Slide

  18. Tedious Builds
    Inlining CSS = Tedious

    View Slide

  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

    View Slide

  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 ? ? Supposed to Yes<br/>Sometimes? Check issues. Try it.<br/>Stats from September 2015<br/>

    View Slide

  21. Not all CSS is inlined
    <br/>/* Do not inline! iOS autolinks */<br/>.ios-footer a {<br/>color: #999999 !important;<br/>}<br/>

    MyCompany.com
    123 Main St
    Springfield, MA

    View Slide

  22. to inline or not?<br/>Source https://github.com/premailer/premailer/issues/242<br/>

    View Slide

  23. Bug: Removed Comments
    Source https://github.com/premailer/premailer/issues/238

    View Slide

  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);
    }

    View Slide

  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

    View Slide

  26. A Build System

    View Slide

  27. Inline and include CSS without mistakes
    Build partials
    Preserve Logic
    Workflow Wishlist

    View Slide

  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

    View Slide

  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

    View Slide

  30. Why Partials?


    Item
    Qty
    Subtotal

    <% @config.products.each do |product| %>
    <%= partial :product, locals: product %>
    <% end %>


    <%= image_tag url %>
    <%= title %>
    <%= quantity %>
    <%= price %>

    TEMPLATE
    PARTIAL

    View Slide

  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…

    View Slide

  32. Faster Workflow with Ruby

    View Slide

  33. 1. Development
    2. Upload Images
    3. Inline CSS
    4. Send Email
    5. Test/Debug
    6. Rinse and Repeat
    Workflow

    View Slide

  34. demo
    Screenshots

    View Slide

  35. Inlined Partial with Preserved Logic

    View Slide

  36. Preserved Logic

    with Regular Expressions

    View Slide

  37. View Slide

  38. View Slide

  39. Example: Complex Partial

    View Slide

  40. View Slide

  41. My Custom Workflow

    View Slide

  42. View Slide

  43. View Slide

  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

    View Slide

  45. Julie Ng
    @jng5
    julie.io
    Fin

    View Slide