RailsでFoundation for Emails 2.0を使ってレスポンシブなHTMLメールを送る

  • 19
    いいね
  • 0
    コメント

 この記事はトレタ Advent Calendar 2016の24日目の記事になります。メリークリスマス!

 今時のメールは大体HTMLメールなのですが、これが結構な曲者です。HTMLメールはブラウザ以上に互換性が低く、色々な罠があります。

 RailsではActionMailerがHTMLメールをサポートしていますが、あまり深いところは助けてくれません。そこでいくつかのツールを合わせて解決して見ます。

HTMLメールの罠

  • CSSの挙動がブラウザと異なる場合がある
  • メール用のResponsive CSSを用意する必要がある
  • CSSはclassではなく、styleでインライン展開する
  • Asset pipelineを使うにはちょっと細工が必要
  • HTMLメールを作るにあたって知っておきたいことにまとまっています

メール用CSSフレームワーク

ブラウザではbootstrapFoundationなど、レスポンシブCSSフレームワークが流行しています。HTMLメール向けもブラウザ向けほど数は多くありませんが、同じようなフレームワークがリリースされています。

 HTMLメールはそれほど表現力は高くないので、ブラウザのCSSフレームワークに比べて能力の差は大きくありません。

Foundation for Emails 2.0

 今回はFoundation for Emailを使って見ます。前はZurb Inkと呼ばれていました。

 Foundation for EmailはSCSSで構築されているので、sass-railsを使いましょう。CSSよりSCSSの方がカスタマイズしやすいのでオススメです。

Railsに導入する

 Foundation for EmailのGemはないので、sass-railsだけをGemfileに追加します

gem 'sass-rails', '~> 5.0'

 続いてFoundation for Emailをダウンロードします。
https://github.com/zurb/foundation-emails/releases から最新版をダウンロードして適当なフォルダに展開します。使うのはSCSSディレクトリだけなので、これをassetsの下に移動します。

mkdir $(RAILS_ROOT)/assets/stylesheets/mailer
mv $(解凍したディレクトリ)/scss $(RAILS_ROOT)/assets/stylesheets/mailer/foundation

次にMailerで使うSCSSファイルを作ります。

$(RAILS_ROOT)/assets/stylesheets/mailer/common.scss
@import "_foundation-custom";
@import "foundation/foundation-emails";

// 以下に好きなSCSSを書いてね & 例
.footer {
  hr {
    width: 94%;
    margin: 40px auto 10px auto;
    height: 2px;
    background-color: #dddddd !important;
    border: 0 !important;
  }
  p, a {
    font-size: 12px;
    color: #cccccc !important;
  }
}
$(RAILS_ROOT)/assets/stylesheets/mailer/_foundation-custom.scss

// _global.scssを参考にFoundationをカスタマイズ
$primary-color: #ff0000;

 最後にlayoutファイルを準備します。公式にテンプレートを参考にしました

app/views/layouts/mailer.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <%= stylesheet_link_tag "mailer/common", media: "all" %>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width">
    <title><%= yield :title %></title>
  </head>
  <body>
    <%= yield %>
    <!-- prevent Gmail on iOS font size manipulation -->
    <div style="display:none; white-space:nowrap; font:15px courier; line-height:0;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
  </body>
</html>

 これで、あとはFoundation for Emailのマニュアルに沿ってHTMLを書いて行ってください。

 HTMLメールでは未だにレイアウトのために<table>タグを使います。気持ち悪いですがそういうものだと思うしかないみたいです。

HTMLの最適化

 HTMLメールの問題は、HTMLの問題とCSSの問題があります。CSSの側の問題はCSSフレームワークで解決できますが、HTMLの書き方の問題が残っています。

 一番大きな問題はgmailがclassをサポートしないため、全てのタグにstyleで指定する必要があることでしょう。

 Railsではこの問題を解決するために premailer-railsを使います。
このGemではstyleへの展開以外に不必要なアトリビュートの削除などを行ってくれます。

画像の扱い

 HTMLメールの扱いの面倒な事の一つに画像の扱いがあります。添付ファイルにして<img src="cid:.."/>で指定する方法と、BASE64でエンコードして<img src="data:image/jpeg;base64.."/>という風にHTMLに含めてしまう方法があります。
 後者の方が楽なのですがOutlookでは表示されないため、前者を使う方が再現性が高いようです。

 その場合は下記のようにして、Mailerの方でattachments[]に表示したい画像ファイルを追加し、.html.erbの方ではattachments[n].urlを使って指定します。

foo_mailer.rb
class FooMailer < ActionMailer::Base
  def email
    attachments['banner.png'] = File.read(Rails.root.join('app/assets/images/banner.png'))
  end
end
email.html.erb
<%= image_tag attachments['banner.png'].url, class: 'banner' %>

メールの確認

 HTMLメールが正しく表示されているのか、各種クライアントで確認するのは大変です。そこでメールのレンダリングを一覧で確認できるWebサービスを使います。

 一番有名なのはLitmusだと思いますが、$99/mo〜(2016/12末現在)とちょっとお高めです。無料や低価格の同種のサービスはないようです。

この投稿は トレタ Advent Calendar 201624日目の記事です。