Outlook、Gmail、スマホでも崩れない必勝HTMLメールコーディング
公開日: 2017.06.08
最終更新日: 2023.01.18
(2023年1月18日更新)
よしだです。
10年近く会っていない人何人かに連絡を入れたら70%の確率でマルチだと思われました。連絡はマメにとるのが良いですね。
さて、今回はHTMLメールのコーディングについての記事です。
近頃、新規HTMLメールのコーディングに携わることが多くなりましたので、備忘録を兼ねて、HTMLメールコーディングの基礎、メールソフト別対策法の解説、それからサンプルを使用してよくあるレイアウトパターンの紹介をしたいと思います。
サンプル
See the Pen Untitled by Maki (@mnakayama) on CodePen.
HTMLメールコーディングの基本
HTMLメールはメールソフトを通して閲覧することが可能ですが、使用可能なHTMLの要素・CSSプロパティはメールソフトによってかなり異なっております。
そして、誰もがスマートフォンを持つ時代になり、あらゆる環境でHTMLメールを閲覧することが可能になりました。その結果、ユーザーの閲覧環境の組み合わせパターンは、様々なメールクライアントとデバイス、そして各々のバージョンの掛け合わせにより、100万種類以上あると言われています。つまりどんな環境でも相違なく閲覧できるHTMLメールを作ることは不可能と言っても過言ではないことを認識しておくことも大切です。
◎基本
・DOCTYPEの設定は、HTML 4.01 Transitional または XHTML 1.0 Transitional (不具合が一般的に少なくなると言われている)
・配信時は文字コードを「iso-2022-jp」に設定(最近は、ほとんどのメールクライアントが「UTF-8」にも対応しているみたいです)
・画像、外部CSSは絶対パス
・CSSは<style>タグ内に記述。必要に応じてstyle属性を使ったインラインCSSで記述
・余白設定は基本td要素に幅や高さを持たせて調整、paddingは上下余白設定のみ(長年の研究の結果、推奨します)
・背景画像は使用しない
◎よく使用するタグ
・table要素
・tr要素
・td要素
・div要素
・p要素
・a要素
・br要素
・img要素
他以下URL参照
https://mailmarketinglab.jp/first-step-to-learn-about-html-mail/
◎よく使用するCSSプロパティ
・margin
・padding
・display
・width
・height
・background-color
・font系(font-family、font-size等)
・line-height
・color
他以下URL参照
https://www.campaignmonitor.com/css/
サンプル解説
よくあるレイアウトパターンをまとめました。
ヘッダー・各コンテンツセクション・フッター、セクション内のタイトル・本文・ボタンなどそれぞれパーツ毎に細かく<table>を設定すると崩れにくい上、レイアウトが崩れた場合でも原因の特定がしやすいです。
◎ヘッダー・メタ情報
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 配信用 --> <!-- <meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp"> --> <!-- /配信用 --> <!-- 編集用 --> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!-- /編集用 --> <meta name="viewport" content="width=640px, user-scalable=yes, target-densitydpi=device-dpi"> <meta name="format-detection" content="telephone=no"> <title>メルマガ</title> </head> </html>
DOCTYPE宣言はほとんどのメールソフトで対応しているHTML4.01にします。文字コードは配信する持に一般的と言われる 「iso-2022-jp」に設定。ただし文字化けすることがあるので、ファイルを編集する際は「shift_jis」または「utf-8」を指定し、配信時に「iso-2022-jp」に戻すとよいと思います。
◎<style>の設定
<style type="text/css"> body { margin: 0; padding: 0; background-color: #ffffff; font-family: "メイリオ", Meiryo, Osaka, "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "MS Pゴシック", "MS PGothic", sans-serif; color: #333; -webkit-text-size-adjust: 100%; } body, td { font-size: 14px; font-style: normal; line-height: 1.5; font-weight: normal; font-variant: normal; text-transform: none; color: #333; } td { word-break:break-all; } body a { color:#1a3181; } img { vertical-align: bottom; } </style>
</head>タグの直前に<style>タグを挿入し、基本スタイルを設定しています。
Androidの@メールでは長いテキストを折り返してくれないので<td>に「word-break: break-all;」を設定してください。
ここから各セクション毎にCSSを追加していきます。
◎コンテナ
<body style="margin: 0; padding: 0; background-color: #ffffff; font-family: 'メイリオ', Meiryo, Osaka, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', 'MS Pゴシック', 'MS PGothic', sans-serif; color: #333; -webkit-text-size-adjust: 100%;"> <div align="center" style="margin: 0 auto;"> <table width="640" cellspacing="0" cellpadding="0" border="0"> <tr> <td width="20" bgcolor="#dddddd"></td> <td width="600" bgcolor="#ffffff"></td> <td width="20" bgcolor="#dddddd"></td> </tr> </table> </div> </body>
幅640pxのHTMLメールの大枠です。大元のテーブルを余白・コンテンツ・余白に三分割しています。この構造が基本となっております。
<body>要素には<style>要素内で指定したCSSをインラインでも記述してください。メールソフトによっては<body>要素の<style>内CSSが効きません。
<table>要素に記述された属性はそれぞれwidth(幅)・cellspacing(セルの間隔)・cellpadding(セル内の余白)・border(外枠の太さ)です。こちらは必ず記述してください。
各<td>要素のwidth属性の値の合計値は親テーブルの幅と合うように記述します。
◎ヘッダー
<!-- ヘッダー --> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="600" class="head"> <tr> <td colspan="4" height="5" bgcolor="#41a334"></td> </tr> <tr> <td colspan="4" height="10"></td> </tr> <tr> <td width="20" align="left"></td> <td width="200" align="left" class="head_logo"><img src="https://www.kannart.co.jp/blog/wp-content/uploads/2017/04/logo.png" width="200" height="50" alt="会社名など" border="0"></td> <td align="right" class="head_date">2017​.05​.31​</td> <td width="20" align="left"></td> </tr> <tr> <td colspan="4" height="10"></td> </tr> <tr> <td colspan="4" height="5" bgcolor="#41a334"></td> </tr> <tr> <td colspan="4" height="20"></td> </tr> </table> <!-- /ヘッダー -->
<style type="text/css"> /* 中略 */ /* ヘッダー */ td.head_logo { vertical-align: middle; } td.head_date { font-size: 18px; line-height: 27px; mso-line-height-rule: exactly; vertical-align: middle; } </style>
td要素のcolspan属性でセルを横方向につなげています。値にはつなげるセルの数を指定します。
メールソフトによってCSSのborder-widthが指定通りに行かないため、上下の5pxのボーダーはtd要素に高さと背景を設定することで表現しています。
CSSのハイライト部分に注目してください。何やら見慣れないプロパティがありますね。この「mso-line-height-rule: exactly;」はOutlookでメイリオフォントを効かせるための記述です。こちらを記述せずにメイリオフォントを指定しますとline-heightがうまく効きません。また、メイリオフォントを使用時、line-heightはpx指定でなければなりません。
◎セクション1
<!-- セクション1 --> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="600" class="sec01"> <tr> <td width="20"></td> <td width="560"> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="560"> <tr> <td><img src="https://www.kannart.co.jp/blog/wp-content/uploads/2017/04/main.png" width="560" height="374" alt="" border="0"></td> </tr> <tr> <td height="20"></td> </tr> <tr> <td align="left" class="sec01_ttl">セクション1のタイトル</td> </tr> <tr> <td align="left" style="" class="sec01_txt">テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</td> </tr> </table> </td> <td width="20"></td> </tr> <tr> <td colspan="3" height="50"></td> </tr> </table> <!-- /セクション1 -->
<style type="text/css"> /* 中略 */ /* セクション1 */ td.sec01_ttl { padding-bottom: 20px; font-size: 30px; font-weight: bold; line-height: 45px; mso-line-height-rule: exactly; vertical-align: middle; } td.sec01_txt { font-size: 20px; line-height: 30px; mso-line-height-rule: exactly; vertical-align: middle; } </style>
メインイメージ、その下にタイトル、テキストを設置したよくあるパターンのひとつです。左右に20pxずつ余白をとり、中央にコンテンツを配置しています。
ハイライトされているセルのようにtd要素の中に新たなtable要素を置くことが可能です。
ちなみにヘッダー・フッター以外、セクション毎に左右20pxずつ余白をとっています。コンテンツ内の大枠に設定してしまった方が楽なのですが、特定のセクションだけ余白やコンテンツ幅が変わるといったことに対応しやすくなるためこのような方法を敢えて採っております。
◎セクション2
<!-- セクション2 --> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="600" class="sec02"> <tr> <td width="20"></td> <td width="560"> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="560"> <tr> <td align="center" bgcolor="#41a334" class="sec02_main-ttl">セクション2のタイトル</td> </tr> <tr> <td height="25" bgcolor="#ffffff"></td> </tr> </table> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="560"> <tr> <td width="200"><img src="https://www.kannart.co.jp/blog/wp-content/uploads/2017/04/img.png" width="200" height="" alt="" border="0"></td> <td width="20"></td> <td width="340"> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="340"> <tr> <td align="left" class="sec02_ttl">タイトル</td> </tr> <tr> <td align="left" class="sec02_txt">テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</td> </tr> <tr> <td align="right" class="sec02_link"><a href="#" class="sec02_link_txt">詳しくはこちら</a></td> </tr> </table> </td> </tr> <tr> <td colspan="3" height="20" bgcolor="#ffffff"></td> </tr> <tr> <td width="200"><img src="https://www.kannart.co.jp/blog/wp-content/uploads/2017/04/img.png" width="200" height="" alt="" border="0"></td> <td width="20"></td> <td width="340"> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="340"> <tr> <td align="left" class="sec02_ttl">タイトル</td> </tr> <tr> <td align="left" class="sec02_txt">テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</td> </tr> <tr> <td align="right" class="sec02_link"><a href="#" class="sec02_link_txt">詳しくはこちら</a></td> </tr> </table> </td> </tr> </table> </td> <td width="20"></td> </tr> <tr> <td colspan="3" height="50"></td> </tr> </table> <!-- /セクション2 -->
<style type="text/css"> /* 中略 */ /* セクション2 */ td.sec02_main-ttl { padding: 20px 0; font-size: 24px; font-weight: bold; line-height: 36px; mso-line-height-rule: exactly; color: #ffffff; vertical-align: top; } td.sec02_ttl { padding-bottom: 10px; font-size: 20px; font-weight: bold; line-height: 30px; mso-line-height-rule: exactly; vertical-align: top; } td.sec02_txt { padding-bottom: 10px; font-size: 16px; line-height: 24px; mso-line-height-rule: exactly; vertical-align: top; } td.sec02_link { line-height: 24px; mso-line-height-rule: exactly; vertical-align: top; } a.sec02_link_txt { text-decoration: underline; font-size: 16px; line-height: 24px; mso-line-height-rule: exactly; } </style>
タイトルとコンテンツは別々の<table>要素区切っています。ハイライト部分は画像とテキストが横並びになる箇所です。rowspan属性を用いて表現することもできますが、Outlook等で崩れる場合があるため、使用は控えた方が良いでしょう。
◎セクション3
<!-- セクション3 --> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="600" class="sec03"> <tr> <td width="20"></td> <td width="560"> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="560"> <tr> <td align="center" bgcolor="#41a334" class="sec03_main-ttl">セクション3のタイトル</td> </tr> <tr> <td height="25" bgcolor="#ffffff"></td> </tr> </table> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="560"> <tr> <td width="270"> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="270"> <tr> <td><img src="https://www.kannart.co.jp/blog/wp-content/uploads/2017/04/img.png" width="270" alt="" border="0"></td> </tr> <tr> <td height="10"></td> </tr> <tr> <td align="left" class="sec03_ttl">タイトル</td> </tr> <tr> <td align="left" class="sec03_txt">テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</td> </tr> <tr> <td align="right" class="sec03_link"><a href="#" class="sec03_link_txt">詳しくはこちら</a></td> </tr> </table> </td> <td width="20"></td> <td width="270"> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="270"> <tr> <td><img src="https://www.kannart.co.jp/blog/wp-content/uploads/2017/04/img.png" width="270" alt="" border="0"></td> </tr> <tr> <td height="10"></td> </tr> <tr> <td align="left" class="sec03_ttl">タイトル</td> </tr> <tr> <td align="left" class="sec03_txt">テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</td> </tr> <tr> <td align="right" class="sec03_link"><a href="#" class="sec03_link_txt">詳しくはこちら</a></td> </tr> </table> </td> </tr> </table> </td> <td width="20"></td> </tr> <tr> <td colspan="3" height="50"></td> </tr> </table> <!-- /セクション3 -->
<style type="text/css"> /* 中略 */ /* セクション3 */ td.sec03_main-ttl { padding: 20px 0; font-size: 24px; font-weight: bold; line-height: 36px; mso-line-height-rule: exactly; color: #ffffff; vertical-align: top; } td.sec03_ttl { padding-bottom: 10px; font-size: 20px; font-weight: bold; line-height: 30px; mso-line-height-rule: exactly; vertical-align: top; } td.sec03_txt { padding-bottom: 10px; font-size: 16px; line-height: 24px; mso-line-height-rule: exactly; vertical-align: top; } td.sec03_link { line-height: 24px; mso-line-height-rule: exactly; vertical-align: top; } a.sec03_link_txt { text-decoration: underline; font-size: 16px; line-height: 24px; mso-line-height-rule: exactly; } </style>
横並び2カラムのレイアウトです。幅560pxのテーブルをコンテンツ(270px)・余白(20px)・コンテンツ(270px)に分け、さらにコンテンツのtd要素の中に<table>要素を入れ子にしています。
◎セクション4
<!-- セクション4 --> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" width="600"> <tr> <td width="20"></td> <td width="560"> <table cellspacing="0" cellpadding="0" border="0" width="560"> <tr> <td colspan="3" height="3" bgcolor="#d2d2d2"></td> </tr> <tr> <td width="3" bgcolor="#d2d2d2"></td> <td> <table cellspacing="0" cellpadding="0" border="0" width="554"> <tr> <td width="35"></td> <td width="484"> <table cellspacing="0" cellpadding="0" border="0" width="484"> <tr> <td align="center" class="sec04_ttl">セクション4のタイトル</td> </tr> </table> </td> <td width="35"></td> </tr> </table> <table cellspacing="0" cellpadding="0" border="0" width="554"> <tr> <td width="10"></td> <td width="534" align="center" style="vertical-align: top;"><img src="https://www.kannart.co.jp/blog/wp-content/uploads/2017/04/img.png" width="534" alt="" border="0"></td> <td width="10"></td> </tr> <tr> <td colspan="3" height="28"></td> </tr> </table> <table cellspacing="0" cellpadding="0" border="0" width="554"> <tr> <td width="40"></td> <td> <table cellspacing="0" cellpadding="0" border="0" width="474"> <tr> <td align="left" class="sec04_txt">テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</td> </tr> <tr> <td> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#cccccc" width="474"> <tr> <td width="474" align="center" class="sec04_link"><a href="#" class="sec04_link_txt">ボタン</a></td> </tr> </table> </td> </tr> <tr> <td height="28" align="left"></td> </tr> </table> </td> <td width="40"></td> </tr> </table> </td> <td width="3" bgcolor="#d2d2d2"></td> </tr> <tr> <td colspan="3" height="3" bgcolor="#d2d2d2"></td> </tr> </table> </td> <td width="20"></td> </tr> <tr> <td colspan="3" height="50" align="left"></td> </tr> </table> <!-- /セクション4 -->
<style type="text/css"> /* 中略 */ /* セクション4 */ td.sec04_ttl { padding: 25px 0; font-size: 25px; font-weight: bold; line-height: 38px; mso-line-height-rule: exactly; } td.sec04_txt { padding-bottom: 30px; font-size: 20px; line-height: 30px; mso-line-height-rule: exactly; } td.sec04_link { padding: 20px 0; line-height: 41px; mso-line-height-rule: exactly; } a.sec04_link_txt { display: block; font-size:34px; font-weight: bold; line-height: 41px; mso-line-height-rule: exactly; color: #fff; text-decoration: none; } </style>
幅3pxのボーダーはCSSで記述せずtd要素に幅や高さ、背景色を持たせて表現しています。CSSのborderプロパティは使用できますが、メールソフトによって線の縦と横の幅がバラバラになるので、このような方法を採っています。
◎フッター
<!-- フッター --> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#41a334" width="600" class="foot"> <tr> <td width="20"></td> <td width="560"> <table cellspacing="0" cellpadding="0" border="0" bgcolor="#41a334" width="560"> <tr> <td align="left" class="foot_txt">テキストが入ります。テキストが入ります。テキストが入ります。<br>テキストが入ります。テキストが入ります。</td> </tr> <tr> <td height="2" bgcolor="#f4e542"></td> </tr> <tr> <td align="center" class="copy">Copyright 2017 XXXX - All Rights Reserved.</td> </tr> </table> </td> <td width="20"></td> </tr> </table> <!-- /フッター -->
<style type="text/css"> /* 中略 */ td.foot_txt { padding: 25px 0; font-size: 18px; line-height: 30px; color: #ffffff; mso-line-height-rule: exactly; } td.copy { padding: 15px 0; font-size: 14px; line-height: 21px; color: #ffffff; mso-line-height-rule: exactly; } </style>
コードを見る限り、セクション1と似たような構造です。黄色のボーダーはセクション4で解説したようにtd要素に幅や高さ、背景色を持たせて表現しています。
メールソフト別対策方法
サンプル解説でちょこちょこ出てきましたが、ここでメールソフト別に崩れやバグの対策方法を紹介します。
◎Outlook
・font-sizeにメイリオを指定した場合、line-heightが意図通りに効かない
そのテキスト要素を囲うタグに対して。px指定のline-heightと「mso-line-height-rule: exactly;」を記述します。
・背景画像、グラデーションが使えない
「background-image」が使えません。色は単色のみとなります。
・td要素のrowspan属性が効かない時がある
rowspanは使用せず、<table>要素をうまく組み合わせて設計する(サンプルのセクション2参照)
◎Gmail
・外部CSSが効かない
<style>タグ内、またはインラインCSSで記述してください。
◎iOS(デフォルトメールソフト)
・内容に電話番号を入れた場合、自動リンク設定される上、スタイルが効かない。
<meta name=”format-detection” content=”telephone=no”>を記述してもメールソフトの上では無効になります。
そのため自動改行の実体参照「​」を数字の後に記述することで解決します。(この記述により一部の4.x系Android端末で崩れる場合があります…)
080​-6666-7777
・iOS10系でのレスポンシブHTMLメールのレイアウト崩れ
iOS10へのアップデートにより、レスポンシブHTMLメールが崩れるという事象が報告されています。
要素をpx指定でなく、%指定にすると改善できる?みたいです。
◎Android
―デフォルトメールソフト(@メール)
・テキストを折り返してくれない。
「word-break:break-all;」を記述すれば解決します。
・機種やOSによってメディアクエリの対応にバラつきがある
長年の研究の結果、XperiaやGalaxyなどの主要機種ではほぼ対応しているようです。
―Gmailアプリ
稀に原因不明の崩れが発生します。アプリ右上アイコンの「自動サイズ変更」を操作するか、以下リンク先の方法で解決することができます。
http://hcondo2000.blogspot.jp/2014/07/androidgmailhtml.html
◎Becky!
・<img>要素に対して、border属性を使用しないと意図しないボーダーが出てくる
<img>要素にborder属性を記述してください。(<img src=”” … border=”0″>)
・左右のpaddingが効かない
左右の余白は<td>要素のwidth属性を使って調節してください。
・「text-align」を指定しない場合、すべて中央ぞろえ
CSSのtext-alignまたはalign属性を逐一記述してください。
テスト配信について
コーディングしたものをブラウザ上で確認して問題がなければ、一旦自身でお使いのメールソフトから自分宛にテスト配信をしてみましょう。
テスト配信による検証作業はHTMLメールコーディングにおいて最も時間がかかります。
対応するメールソフトが多ければ多い程、修正に時間がかかり、あるメールソフトの崩れを直したら、今度は別のあるメールソフトで崩れるなんてことにも遭遇するかもしれません。
上記の基本やバグ対策を行えばおそらく問題ないかと思います。
おわりに
テーブルコーディングは慣れてしまえば大したことはありません。
HTMLメールコーディングで最も大変なのは検証作業です。実際に配信してみないと崩れやバグの発見ができないため、修正作業に時間がかかることが多々あるかと思います。
先に述べました「HTMLメールコーディングの基本」や「メールソフト別対策方法」を考慮してコーディングすれば、大概のメールソフトはカバーできると思います。
また、昨今レスポンシブHTMLメールが普及していますが、スマホOSの大きなアップデートによって今まで正常に閲覧できていたHTMLメールのレイアウトが崩れた、なんて場合があるので、レスポンシブHTMLメールに関しては「このように設計すれば絶対崩れない」という方法は現段階ではわかっておりません。なにかわかりましたら、レスポンシブHTMLメールについての記事も書いていこうかと思います。
HTMLメルマガの制作、メールマーケティングに関するご相談なら
カンナートにおまかせください!ご相談はこちらから。
※お電話でのお問い合わせはこちら※
03-6432-9033
(平日 10:00〜18:00まで)