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 full-size 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 full-size slide

  3. Email != hard

    View full-size 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 full-size 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 full-size slide

  6. Email = more HTML

    View full-size 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 full-size slide

  8. Bulletproof = more code
    and

    View full-size slide

  9. Button


    A button →

    View full-size 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 full-size slide

  11. Tables for Layouts

    View full-size slide

  12. Grid with s


    … Column 1 …



    … Column 2 …


    View full-size 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 full-size 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 full-size slide

  15. Tedious Builds

    View full-size slide

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

    View full-size slide

  17. Tedious Builds
    Inlining CSS = Tedious

    View full-size slide

  18. 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 full-size slide

  19. 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 full-size slide

  20. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  23. 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 full-size slide

  24. 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 full-size slide

  25. A Build System

    View full-size slide

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

    View full-size slide

  27. 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 full-size slide

  28. 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 full-size slide

  29. Why Partials?


    Item
    Qty
    Subtotal

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


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

    TEMPLATE
    PARTIAL

    View full-size slide

  30. 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 full-size slide

  31. Faster Workflow with Ruby

    View full-size slide

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

    View full-size slide

  33. demo
    Screenshots

    View full-size slide

  34. Inlined Partial with Preserved Logic

    View full-size slide

  35. Preserved Logic

    with Regular Expressions

    View full-size slide

  36. Example: Complex Partial

    View full-size slide

  37. My Custom Workflow

    View full-size slide

  38. 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 full-size slide

  39. Julie Ng
    @jng5
    julie.io
    Fin

    View full-size slide