この記事はトレタ Advent Calendar 2016の24日目の記事になります。メリークリスマス!
今時のメールは大体HTMLメールなのですが、これが結構な曲者です。HTMLメールはブラウザ以上に互換性が低く、色々な罠があります。
RailsではActionMailerがHTMLメールをサポートしていますが、あまり深いところは助けてくれません。そこでいくつかのツールを合わせて解決して見ます。
HTMLメールの罠
- CSSの挙動がブラウザと異なる場合がある
- メール用のResponsive CSSを用意する必要がある
- CSSは
class
ではなく、style
でインライン展開する - Asset pipelineを使うにはちょっと細工が必要
- HTMLメールを作るにあたって知っておきたいことにまとまっています
メール用CSSフレームワーク
ブラウザではbootstrapやFoundationなど、レスポンシブ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ファイルを作ります。
@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;
}
}
// _global.scssを参考にFoundationをカスタマイズ
$primary-color: #ff0000;
最後にlayoutファイルを準備します。公式にテンプレートを参考にしました
<!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;"> </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
を使って指定します。
class FooMailer < ActionMailer::Base
def email
attachments['banner.png'] = File.read(Rails.root.join('app/assets/images/banner.png'))
end
end
<%= image_tag attachments['banner.png'].url, class: 'banner' %>
メールの確認
HTMLメールが正しく表示されているのか、各種クライアントで確認するのは大変です。そこでメールのレンダリングを一覧で確認できるWebサービスを使います。
一番有名なのはLitmusだと思いますが、$99/mo〜(2016/12末現在)とちょっとお高めです。無料や低価格の同種のサービスはないようです。