HTMLメール制作で絶対知っておくべき落とし穴まとめ(Mailtrapで検証)
最近、HTMLメールの表示崩れを直す機会がありました。
元のレイアウトはdivタグベースかつflexレイアウトで組まれていましたが、
最終的にtableレイアウトへと全面的に組み直しました。
※初めてHTMLメールに関する対応を行いましたが、Webページを作る際とは随分と勝手が違うなと感じました…
(シーラカンスかよと思いました。)
そんなわけで、今回はHTMLメールを作る際の注意点を簡単にまとめたいと思います。
HTMLメールの崩れを修正する方法
私は以下の流れで修正を行いました。
- ローカルでは Mailtrap に向けて送信して確認する
- 実際にテスト環境で各メールクライアントに向けて送信して確認する
Mailtrapに向けて送信して確認する方法
簡単に確認できるソースコードを提供します。
※node.jsを用いる例です。もちろん他の好きな言語やフレームワークを使っても大丈夫です。
実際の運用では環境変数などにMailtrapの情報を持たせるのがおすすめですが、ここでは分かりやすさのためにコードに直接書いています。
const nodemailer = require("nodemailer");
// Mailtrapの「Email Testing」 > Inbox > Integrationに表示される値を使う
const transporter = nodemailer.createTransport({
host: "sandbox.smtp.mailtrap.io",
port: 2525, // Mailtrap Email Testingのデフォルトポート
auth: {
user: "あなたのUsername", // ここを書き換え
pass: "あなたのPassword", // ここを書き換え
},
});
// HTMLメールのテスト用コンテンツ
const html = `
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>HTMLメール検証</title>
<style>
.flex-header {
display: flex;
justify-content: space-between;
padding: 16px;
margin: 16px 0;
background-image: linear-gradient(45deg, #2196f3, #e91e63);
color: #ffffff;
}
</style>
</head>
<body style="margin:0; padding:0;">
<h1 style="font-size:20px; margin:16px;">HTMLメールのCSS検証サンプル</h1>
<!-- flex依存で崩れやすい部分 -->
<div class="flex-header">
<div>左側(flex)</div>
<div>右側(flex)</div>
</div>
<!-- table レイアウトで安全な部分 -->
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin-top:16px;">
<tr>
<td align="left" style="font-size:14px; padding:4px 16px;">
左側(tableレイアウト)
</td>
<td align="right" style="font-size:14px; padding:4px 16px;">
右側(tableレイアウト)
</td>
</tr>
</table>
<p style="font-size:14px; line-height:1.6; margin:16px;">
このメールは、HTMLメールで flex / margin / background-image などが
各クライアントでどう表示されるか確認するためのテストメールです。
</p>
</body>
</html>
`;
async function main() {
try {
const info = await transporter.sendMail({
from: '"HTML Mail Tester" <test@example.com>',
to: "test@example.com", // MailtrapのInboxなら何でもOK
subject: "HTMLメールのCSS検証サンプル",
html,
});
console.log("メール送信完了:", info.messageId);
} catch (err) {
console.error("送信エラー:", err);
}
}
main();
※以下のコマンドで実行できます。
node index.js
Mailtrap側の準備
以下のように準備してください。
- 未登録の場合はMailtrapアカウントを作成※GoogleアカウントやGithubアカウントで簡単に登録できます。
- 「Email Testing」のInboxをひとつ作成(デフォルトのままでもOK)
- 前の手順で作成したSandboxを開く
- Integrationタブに
UsernameとPasswordがあるので、それをコピーして先述のコードに貼り付け
HTMLメールを作成する際の注意点

ここからは、上記の画像のようにHTMLメールをMailtrap上で参照すると表示されるHTML Checkタブの表示を見ながら、HTMLメールを作成する際の注意点をまとめたいと思います。
(サンプルコードを実行すると、上記の画像のような結果になりました。)
※HTML Checkタブの動きとしては、HTMLに含まれているタグに紐づく注意点を表示するものです。
以下の点に留意する必要があります。
- タグが含まれていれば警告を表示するので、実際には問題がなくても警告が表示される場合があります。(例えば、displayがインラインでCSSに指定されている場合、flexを用いていなくてもflexに関連する注意点が表示されます。)
- 日本ではあまり使われていないメーラーに関する警告や、古いバージョンのメーラーに関する警告も出すので、どこまで対応するのか事前に要件を確認する必要があります。
bodyタグはdivタグに置換される

警告の英文の通り、主要なメールクライアントでは <body> タグが
安全な属性だけを持つ独自の<div>に置き換えられます。
そのため<body>にインラインスタイルを指定していた場合でも、
各メールクライアントでサポートされていないスタイルは自動的に削除され、
意図した見た目にならない可能性があります。
※どのスタイルがサポートされていないかは後述します。
justify-contentは多くのメールクライアントでサポートされていない

justify-contentは、flexboxを前提としたプロパティのため、HTMLメールではほとんどの
メールクライアントでサポートされていません。
画像にある通り、GmailやOutlookなど主要クライアントは赤アイコン=非対応で、
Notesを見ると、2020年時点では完全に非対応、2023年以降の一部バージョンで部分的に対応し始めたという記載があります。
実務的には、justify-contentは現在でも広く非対応と考えるべきで、
HTMLメールでは使用しないのが安全です。
※サンプルコードにも書いている通り、tableレイアウトを用いましょう。
スタイルはインラインで書くべき

画像の警告が示す通り、HTMLメールにおける<style>タグは
メールクライアントによっては
削除されたり、無視されたり、位置によって動作が壊れたりします。
特にGmailやOutlookは<body>内の<style>を削除したり、
HTML構造を書き換えて<head>そのものを消すこともあるため、
スタイルが反映される保証がありません。
2020年のバージョンでは非対応、2023年には一部対応、
その後のバージョンでは再び非対応というように、挙動が非常に不安定です。
実務では<style>を使用せず、すべてインラインCSSで記述するのが安全です。
display: flexはほぼ使えない

display:flexは、HTMLメールではほとんどのメールクライアントで非対応です。
Notesを見ると、2020年のバージョンでは非対応、2020〜2021の一部バージョンで
一時的にサポートされたものの、その後また非対応に戻るなど、
クライアントやバージョンによって挙動が安定しません。
また、Gmailでは、Gmailアカウント以外で受信した場合は動かないなど、
同じアプリ内でも挙動が異なるケースがあります。
実務的には、display:flexはHTMLメールでは広く非対応と考えるべきで、
レイアウトはすべてtableベースで構築するのが安全です。
background-imageもほぼ使えない

background-image は、HTMLメールではほとんどのメールクライアントで非対応または部分対応で、
非常に不安定なプロパティです。
特にGmailでは、background-image: url(...)を書くと安全性の観点から
style 属性全体が削除される場合があり、背景画像だけでなく他のスタイルも
まとめて消えてしまうことがあります。
またWindows版OutlookではWeb標準のCSSが使えず、VMLという
Microsoft独自の記法で背景画像を指定する必要があります。
Yahoo!Mailでは複数画像の指定が正しくパースされず、画像URLを
クォートで囲まないと読み込めないなど、クライアントごとに仕様が
まったく異なるため、安定した背景画像の表示は困難です。
実務では、HTMLメールでbackground-imageは「原則使わない」、
背景色(background-color)や画像そのものを<img>として配置する方式が推奨されます。
displayを使った近代的なレイアウトは使えない

displayプロパティは、HTMLメールでは多くの値が非対応または部分対応で、
特に flex/grid/flow-root/contents/inline-flexなどの近代的な値は
ほぼすべてのメールクライアントで無視されます。
Outlookではdisplay:none以外の値が効かず、display:noneでさえ
入れ子のtableに継承されないバグがあります。
Yahoo!Mailでも大量のdisplay値がサポートされていません。
このようにdisplayを使ったレイアウトはHTMLメールでは実質不可能であり、
レイアウトはすべてtable要素で組むことが推奨されています。
lang属性を要素単位で指定しない

lang属性は、本来アクセシビリティや文章の読み上げ処理のために
HTMLで使用される属性ですが、HTMLメールではクライアントによって
対応状況が大きく異なります。
特にYahoo!Mailでは<td lang="...">のような要素単位の
lang属性が無視される場合があり、細かいレベルでの言語指定は反映されません。
またNotesの通り、2020年のバージョンでは対応していたものが
2021年のバージョンで非対応になるなど、クライアントやバージョンに
よって挙動が安定していません。
実務上は、HTMLメールでlang属性を厳密に使う必要性は低く、
文書全体を示す <html lang="ja"> 程度に留めるのが安全です。
marginの挙動が不安定

marginはHTMLメールでは非常に扱いにくく、クライアントごとに
対応が大きく異なります。Notesの通り、負のmargin(negative margin)は
GmailやOutlookでは無視され、margin: autoもOutlook Windowsが
非対応のため中央寄せができません。
さらにOutlookでは、marginとbackground-colorを組み合わせると
背景色がmargin領域にまで広がって描画されるバグがあり、クライアント間で
大きな見た目の差が生じます。また<span>や<body>のmarginが
無視されるクライアントも存在します。
このようにmarginはHTMLメールでは非常に不安定なため、余白は
paddingを使用し、レイアウトはtableベースで組むのが安全です。
Outlookでline-heightの挙動が不安定

HTMLメールではline-heightの挙動が特にOutlookで不安定です。
Notesの通り、Outlook(Windows版)はline-height: 20pxや1.4emといった
単位付きの指定が正しく反映されず、行間が変わってしまうバグがあります。
こうしたケースではmso-line-height-rule: exactly;を併用することで、
Outlookでも安定した行間が得られます。
また、一部クライアントではline-height: normalがサポートされていなかったり、
実際の表示が非常にまちまちになるため、HTMLメールではline-heightは
1.5のように数値で指定するのが最も安全です。
Outlookではpaddingの挙動が制限される

HTMLメールではpaddingの挙動がOutlook(Windows版)で大きく制限されます。
Notesの通り、Outlookはpaddingを「table セル(<td>)に対してのみ」
サポートしており、<div>や<p>などに指定したpaddingは基本的に無視されます。
さらに、縦方向のpaddingにバグがあり、同じ行にある複数の<td>に異なる
padding-topやpadding-bottomを設定した場合、Outlookでは
「行内で最も大きいpaddingに強制的に統一される」という問題があります。
このため、HTMLメールではpaddingは必ず<td>に記述し、
上下方向のpaddingを行内で揃えるか、必要に応じて行を分割する設計が必要です。
width属性のOutlookでの挙動に注意

HTMLメールでは、width属性の挙動がOutlook(Windows版)で特に不安定です。
Notesの通り、<img width="100%">のようなパーセント指定は
「親要素ではなく画像ファイル自身の幅」を基準に計算されるバグがあり、
Outlookでは画像が思わぬ大きさで表示されてしまいます。
また、width属性で指定されたサイズはWindowsのDPIスケール
(120dpi/125% 表示など)に追従せず、画像だけが拡大縮小されない問題もあります。
このため、HTMLメールではwidthは属性だけに依存せず、
style="width:600px;"のようにCSSと併用したり、
ラップ用のtableを活用してレスポンシブにするのが安全です。
Discussion