email-html-mjml について
email-html-mjml は、MJML 5.x でレスポンシブなメールテンプレートを作成し、HTML にコンパイルするスキルです。複数のメールクライアントへの対応、厳格な検証、アクセシビリティを重視し、ソースとコンパイル済みファイルの両方を出力します。
主な機能
- 01MJML 5.x テンプレート生成
- 02HTML のコンパイルと検証
- 03Outlook と Gmail の互換性ガイド
- 04アクセシビリティとダークモードの確認
- 05MJML コンポーネント資料
活用シーン
- 01トランザクションメールの作成
- 02プロモーションメールのレイアウト作成
- 03レスポンシブなニュースレターの準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ framix-team/ skill-email-html-mjml --skill email-html-mjmlインストール後、Claude Code で/email-html-mjmlを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
compilation.mdLICENSEmjml-reference.mdassets/examples/basic-layout.mjmlnewsletter.mjmlorder-confirmation.mjmlpromo-sale.mjmlassets/examples/partials/footer.mjmlcomponents/advanced.mdcontent.mdhead.mdinteractive.mdlayout.md詳細
email-html-mjml — レスポンシブメール開発者
有効で、さまざまなメールクライアントに対応する MJML 5.x テンプレートを生成し、本番環境で使える HTML にコンパイルします。最優先事項は互換性です。Outlook(2013~365)、Gmail(ウェブ/アプリ)、Apple Mail、主要なモバイルクライアントに対応します。すべての出力は --config.validationLevel=strict でコンパイルでき、Gmail の 102KB のクリップ上限を超えない必要があります。
ワークフロー
- 要件を把握する — ユーザーのメッセージと会話の文脈から、メールの種類、ブランドカラー、コンテンツを推測します。本当に不足していて作業の妨げになる情報だけを尋ねます(例:カラーが指定されていないのに、レイアウトにブランドカラーのセクションがある場合)。最初から質問を並べ立てないでください。
- レイアウトを計画する — コードを書く前に、構成(1 カラム、2 カラムのグリッド、ヒーロー+コンテンツなど)を決めて伝えます。
- コンポーネントのリファレンスを読み込む — MJML を書く前に、以下のコンポーネントインデックスから関連ファイルを読みます。
- MJML を生成する — 完全で有効な MJML を
<mjml>から書き始め、完全な<mj-head>を含めます。 - コンパイルする —
compilation.mdに従います。--config.minify=trueを指定してnpx mjmlを実行します。 - 両方のファイルを納品する —
.mjmlのソースとコンパイル済みの.htmlを必ず出力します。
9 つのエンジニアリングルール
- 構造の整合性 — すべての視覚コンテンツは、必ず
<mj-section>内の<mj-column>に含めます。セクションはネストできません。 - レスポンシブのデフォルト設定 — 幅は 600px を前提とします。横並びの要素(ソーシャルバー、ロゴの行など)がモバイルで縦に積み重ならないよう、
<mj-group>を使います。カラム間の間隔を均等にするには、パディングで調整するのではなく<mj-section gutter="...">を使います。 - Outlook との互換性 — ウェブフォントには
<mj-font>を使います(Times New Roman へのフォールバックを防ぎます)。必ずフォールバックスタック(Arial、sans-serif)を指定します。<mj-section>の背景画像には、必ずbackground-sizeとフォールバックのbackground-colorの両方を設定します。 - Gmail の最適化 — カスタム CSS には
<mj-style>のinline="inline"を使います。重要なスタイルには CSS クラスよりコンポーネント属性(color、font-size)を優先します。 - ダークモード — 明示的に依頼された場合、または明るい背景が強い強制反転を引き起こすメールの場合は、ダークモードに対応します。以下のダークモードパターンを参照してください。
- アクセシビリティ — すべての
<mj-image>にaltを指定します。必ず<mj-title>を設定します(aria-labelに反映されます)。WCAG 2.1 AA のコントラスト比 4.5:1 を維持します。見出しのロールにはmj-html-attributesを使います。mj-textにrole/aria-level属性を直接指定すると、strict 検証で許可されません(以下のアクセシビリティチェックリストを参照)。 - スタイル指定の効率化 —
<mj-all>、コンポーネントのデフォルト値、<mj-class>とともに<mj-attributes>を使い、繰り返しのインラインスタイルをなくします。 - ヒーローセクション — 全幅のヒーローバナーには
<mj-hero>を使います。非対応のクライアントでは通常のセクションにフォールバックします。<mj-accordion>と<mj-carousel>はクライアントの対応状況が悪く、実用的でないため避けます。 - テンプレート処理への対応 — 単純な補間(
{{firstName}})はラップする必要がありません。テキスト、属性、mj-title、mj-previewをそのまま通過します。<または>を含むブロックタグ({% if x < 5 %}、{{#if a<b}})に限り、`` による保護が必要です。保護しないと、minify によって気付かないうちに破損します。カラム内のコンテンツコンポーネント間にある<mj-raw>は、その内容を</tr>と<tr>の間に出力するため、無効なマークアップになります。mj-rawはセクション間に配置し、テンプレートタグを<mj-style>内に入れないでください(compilation.mdを参照)。
重大な注意点
MJML 5 では mj-include はデフォルトで無効です:
- インクルードが明示的に有効化されていない限り、
<mj-include>タグは無視されます。これは MJML 4 からの意図的なセキュリティ変更です - CLI:
--config.allowIncludes trueを追加します。Node API:ignoreIncludes: falseを渡します --config.includePath(CLI)またはincludePath(Node)で許可するディレクトリの範囲を指定します。サポートされるインクルードは MJML、HTML、CSS のみです- テンプレート自身のディレクトリ外にあるパーシャルは、そのディレクトリが許可リストにない限り拒否されます
--config.validationLevel=strictではこの問題を検出できません — インクルードが破棄されても、終了コードは0のままで、.htmlも書き出されます。コンパイルが成功したからといって、インクルードが反映されたとは限りません。納品前に、出力内に既知のパーシャルの内容があるか grep で確認してください- インクルードから期待していたコンテンツがコンパイル済みテンプレートにない場合は、まずこれを確認してください
Outlook:
- 背景画像:VML が生成されるのは
<mj-section>と<mj-hero>のみです。それ以外では生成されません - 背景の位置:キーワード値のみ(
top、center、bottom) — ピクセル値は無視されます background-repeat="no-repeat"には、必ず明示的なbackground-sizeを組み合わせてください- フォントのフォールバック:
<mj-font>は MSO 条件付きコメントを介して、Outlook から@font-faceを隠します
Gmail:
- 重要なレイアウトにはコンポーネント属性を使用してください — CSS クラスは削除される場合があります
- 102KB のクリップ制限:必ず
--config.minify=trueを指定してコンパイルしてください
iOS/Android のスタッキング:
- MJML 5 の minify では、タグ間の空白が削除されなくなりました —
htmlnanoは連続した空白を1つのスペースにまとめますが、html-minifierは空白を削除していました(確認済み:v4 は<![endif]--><div class="mj-column-per-50"を出力し、v5 は<![endif]--> <div ...を出力します)。現在も有効なスタッキング対策は、MJML が親の<td>に設定するfont-size:0pxで、これはどちらのバージョンでも出力されます - v4 の空白削除を復元するには、
--config.minifyOptions '{"collapseWhitespace":"all"}'を指定します(JSON 文字列形式が必要です) - タグ間の空白は、
<mj-group>内でもスタッキングを引き起こします
vertical-align のバグ:
- セクション内のいずれかのカラムで
vertical-alignを設定する場合、そのセクション内のすべてのカラムで明示的に設定する必要があります
JavaScript:
- すべてのメールクライアント(Gmail、Outlook、Apple Mail、iOS Mail)で JS は完全にブロックされます。
onclick、クリップボード API、あらゆる種類のインタラクティブ機能は使用できません。コピー ボタンやトグルなど、インタラクティブに見える要素は装飾にすぎません。
ダークモードのパターン
<mj-head>
<mj-raw>
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
</mj-raw>
<mj-style inline="inline">
.dark-logo { display: none !important; }
</mj-style>
<mj-style>
@media (prefers-color-scheme: dark) {
.light-logo { display: none !important; }
.dark-logo { display: block !important; }
}
</mj-style>
</mj-head>
安全なニュートラルカラー:#000000 ではなく #121212、#FFFFFF ではなく #F1F1F1 — 強制的な色反転による違和感を防ぎます。
アクセシビリティチェックリスト
<mj-title>が設定されている(スクリーンリーダー用のメールラベル+aria-label)- ルートの
<mjml>タグにlang属性がある - すべての
<mj-image>と<mj-social-element>にaltがある - 見出しロールは
mj-html-attributesで設定する(mj-textに直接属性として設定しない):<mj-html-attributes> <mj-selector path=".email-heading div"> <mj-html-attribute name="role">heading</mj-html-attribute> <mj-html-attribute name="aria-level">1</mj-html-attribute> </mj-selector> </mj-html-attributes> <mj-text css-class="email-heading" ...>Heading text</mj-text> - すべてのテキスト/背景の組み合わせでコントラスト比が 4.5:1 以上
- 画像にテキストを埋め込まない — 必ず実際の
<mj-text>ブロックを使用します
コンポーネント一覧
MJML を記述する前に、使用するコンポーネントのファイルを読んでください。
| グループ | コンポーネント | 読み込むタイミング | ファイル |
|---|---|---|---|
| Head | mj-attributes, mj-font, mj-style, mj-preview, mj-breakpoint, mj-html-attributes | head、グローバルスタイルの設定時 | components/head.md |
| Layout | mj-body, mj-section, mj-column, mj-group, mj-wrapper | 構造/グリッドの構築時 | components/layout.md |
| Content | mj-text, mj-image, mj-button, mj-divider, mj-spacer, mj-table | コンテンツブロックの追加時 | components/content.md |
| Interactive | mj-accordion, mj-carousel, mj-social, mj-navbar | インタラクティブ要素またはソーシャル要素の追加時 | components/interactive.md |
| Advanced | mj-hero, mj-raw, mj-include | ヒーローバナー、テンプレートタグ、パーシャルの追加時 | components/advanced.md |
一般的なリファレンス(階層、終了タグ、検証、幅の計算、Gmail のクリップ制限):mjml-reference.md
コンパイル
ワークフローの全体については、compilation.md をお読みください。主要なコマンド:
npx mjml template.mjml -o dist/template.html --config.minify=true --config.validationLevel=strict
必ず守るルール:
npm install -g mjmlは絶対に実行しないでください- 常に
npxまたは./node_modules/.bin/mjmlを使用してください package.jsonに mjml が含まれていない場合は、npm install -D mjmlを提案してください
例
4つすべてのファイルが、MJML 5.4.0 で --config.validationLevel=strict --config.minify=true を指定してもエラーなくコンパイルできます。
| ファイル | 参考にする用途 |
|---|---|
assets/examples/basic-layout.mjml | 構成のみ。MJML ドキュメントの例:6セクション構成(ヘッダー、画像ヒーロー+ボタン、イントロ、画像+テキストの2カラム、アイコンの3カラム、ソーシャル行)。意図的に最小限の内容にしています。mj-head なし、ダークモードなし、プレースホルダーの文面を使用しています。本番用テンプレートではありません。 |
assets/examples/order-confirmation.mjml | トランザクションメール。完全な mj-head(mj-attributes + mj-class + mj-font + mj-html-attributes)、scope="col" ヘッダー付きのレシート用 mj-table、htmlmin:ignore を指定した mj-raw 内の Handlebars、条件付きブロック、および partials/footer.mjml の mj-include。--config.allowIncludes true が必要です。 |
assets/examples/promo-sale.mjml | プロモーションメール。mj-hero と mj-section の背景画像(VML を生成)、mj-navbar、折り返されない行の mj-group、mj-social、mj-breakpoint に加え、MJML 5 の gutter/border/inner-padding 属性。 |
assets/examples/newsletter.mjml | エディトリアル+ダークモード。前述のダークモードのパターン全体、mj-wrapper、aria-level の1と2に対する mj-html-attributes、各セクションのすべてのカラムに設定された vertical-align。 |
これらのファイルに含まれる文面、画像 URL、ブランドはすべてプレースホルダーです。置き換えてください。そのまま本番環境に出さないでください。
出力
常に以下を納品してください。
<name>.mjml— 完全な MJML ソース(編集可能、バージョン管理可能)<name>.html— コンパイル済みの出力(本番環境で使用可能。ESP 経由で送信)
メールの種類に合わせてファイル名を付けてください:welcome.mjml、promo-sale.mjml、order-confirmation.mjml