email-html-mjml
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseemail-html-mjml — Responsive Email Developer
email-html-mjml — 响应式邮件开发工具
Generate valid, cross-client MJML 4.x templates and compile them to production-ready HTML. The primary goal is compatibility: Outlook (2013–365), Gmail (web/app), Apple Mail, and major mobile clients. Every output must be compilable with and survive Gmail's 102KB clip limit.
--config.validationLevel=strict生成符合规范、跨客户端兼容的MJML 4.x模板,并将其编译为可用于生产环境的HTML。核心目标是兼容性:支持Outlook(2013–365)、Gmail(网页版/应用版)、Apple Mail以及主流移动客户端。所有输出内容必须能够通过编译,且不超过Gmail的102KB内容截断限制。
--config.validationLevel=strictWorkflow
工作流程
- Gather requirements — Infer email type, brand colors, and content from the user's message and conversation context. Ask only for what is genuinely missing and blocking progress (e.g., no colors provided and the layout has branded sections). Never front-load a questionnaire.
- Plan layout — Decide and announce the structure before writing code (single-column, 2-col grid, hero + content, etc.)
- Load component references — Read the relevant file(s) from the Component Index below before writing any MJML
- Generate MJML — Write complete, valid MJML starting from with a full
<mjml><mj-head> - Compile — Follow . Run
compilation.mdwithnpx mjml--config.minify=true - Deliver both files — Always output source AND compiled
.mjml.html
- 收集需求 — 从用户的消息和对话语境中推断邮件类型、品牌颜色和内容。仅询问真正缺失且会阻碍进度的信息(例如,未提供颜色但布局包含品牌相关板块)。切勿一开始就抛出一堆问题。
- 规划布局 — 在编写代码前确定并告知结构(单栏、双栏网格、首屏横幅+内容等)
- 加载组件参考 — 在编写任何MJML代码前,先阅读下方组件索引中的相关文件
- 生成MJML — 编写完整、合规的MJML代码,从标签开始,包含完整的
<mjml><mj-head> - 编译 — 遵循的要求。使用
compilation.md命令并添加npx mjml参数--config.minify=true - 交付两个文件 — 始终输出源文件和编译后的
.mjml文件.html
9 Engineering Rules
9条工程规则
- Structural Integrity — All visual content MUST be in inside
<mj-column>. Sections cannot be nested.<mj-section> - Responsive Defaults — Assume 600px width. Use to prevent mobile stacking for side-by-side elements (social bars, logo rows).
<mj-group> - Outlook Compatibility — Use for web fonts (prevents Times New Roman fallback). Always provide a fallback stack (Arial, sans-serif). For
<mj-font>background images, always set both<mj-section>and a fallbackbackground-size.background-color - Gmail Optimization — Use on
inline="inline"for custom CSS. Prefer component attributes (<mj-style>,color) over CSS classes for critical styles.font-size - Dark Mode — Include dark mode support when explicitly requested or when the email has a light background that would cause harsh forced-inversion. See the Dark Mode Pattern below.
- Accessibility — Every MUST have
<mj-image>. Always setalt(populates<mj-title>). Maintain WCAG 2.1 AA 4.5:1 contrast. For heading roles, usearia-label— directmj-html-attributes/roleattributes onaria-levelare illegal under strict validation (see Accessibility Checklist below).mj-text - Styling Efficiency — Use with
<mj-attributes>, component defaults, and<mj-all>to eliminate repetitive inline styles.<mj-class> - Hero Sections — Use for full-bleed hero banners; it falls back to a regular section in unsupported clients. Avoid
<mj-hero>and<mj-accordion>— client support is too poor to be useful.<mj-carousel> - Templating Support — Wrap dynamic tags (Handlebars/Liquid) in to protect them from the MJML parser.
<mj-raw>
- 结构完整性 — 所有可视化内容必须放在内的
<mj-section>中。Section不能嵌套。<mj-column> - 响应式默认设置 — 默认宽度设为600px。使用防止移动端的并排元素堆叠(如社交栏、Logo行)。
<mj-group> - Outlook兼容性 — 使用引入网页字体(避免回退到Times New Roman)。始终提供备选字体栈(Arial, sans-serif)。对于
<mj-font>的背景图片,始终同时设置<mj-section>和备选background-size。background-color - Gmail优化 — 在上使用
<mj-style>来处理自定义CSS。优先使用组件属性(inline="inline"、color)而非CSS类来设置关键样式。font-size - 深色模式 — 当用户明确要求,或邮件为浅色背景可能导致强制反转效果过于刺眼时,需支持深色模式。请参考下方的深色模式方案。
- 可访问性 — 每个必须设置
<mj-image>属性。始终设置alt(用于填充<mj-title>)。保持WCAG 2.1 AA标准的4.5:1对比度。对于标题角色,使用aria-label— 在严格验证规则下,直接在mj-html-attributes上设置mj-text/role属性是不允许的(请参考下方的可访问性检查清单)。aria-level - 样式效率 — 使用结合
<mj-attributes>、组件默认值和<mj-all>来消除重复的内联样式。<mj-class> - 首屏横幅板块 — 使用实现全屏宽度的首屏横幅;在不支持的客户端中会回退为普通板块。避免使用
<mj-hero>和<mj-accordion>— 客户端支持度极低,实用性差。<mj-carousel> - 模板支持 — 将动态标签(Handlebars/Liquid)包裹在中,避免被MJML解析器处理。
<mj-raw>
Critical Gotchas
关键注意事项
Outlook:
- Background images: VML only generated for and
<mj-section>— nowhere else<mj-hero> - Background positioning: keyword values only (,
top,center) — pixel values ignoredbottom - Always pair with explicit
background-repeat="no-repeat"background-size - Font fallback: hides
<mj-font>from Outlook via MSO conditional comments@font-face
Gmail:
- Use component attributes for critical layout — CSS classes may be stripped
- 102KB clip: always compile with
--config.minify=true
iOS / Android stacking:
- Always compile with — removes whitespace between
--config.minify=truecolumnsinline-block - Whitespace between tags causes stacking even inside
<mj-group>
Vertical-align bug:
- If any column in a section sets , ALL columns in that section must explicitly set it
vertical-align
JavaScript:
- JS is completely blocked in all email clients (Gmail, Outlook, Apple Mail, iOS Mail). No , no clipboard API, no interactivity of any kind. Interactive-looking elements (copy buttons, toggles) are purely decorative.
onclick
Outlook相关:
- 背景图片:仅会为和
<mj-section>生成VML代码 — 其他标签不支持<mj-hero> - 背景定位:仅支持关键字值(、
top、center) — 像素值会被忽略bottom - 始终将与明确的
background-repeat="no-repeat"配合使用background-size - 字体回退:通过MSO条件注释隐藏
<mj-font>,避免Outlook出现问题@font-face
Gmail相关:
- 使用组件属性设置关键布局 — CSS类可能会被移除
- 102KB截断限制:编译时始终添加参数
--config.minify=true
iOS / Android堆叠问题:
- 编译时始终添加参数 — 移除
--config.minify=true列之间的空白inline-block - 标签之间的空白会导致即使在内的元素也发生堆叠
<mj-group>
垂直对齐Bug:
- 如果某个板块中的任意列设置了,该板块中的所有列必须显式设置此属性
vertical-align
JavaScript:
- 所有邮件客户端(Gmail、Outlook、Apple Mail、iOS Mail)完全禁止JS。不支持、剪贴板API或任何交互功能。看似可交互的元素(复制按钮、切换控件)仅为装饰性。
onclick
Dark Mode Pattern
深色模式方案
xml
<mj-head>
<mj-raw>
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
</mj-raw>
<!-- Light logo visible by default; dark logo hidden -->
<mj-style inline="inline">
.dark-logo { display: none !important; }
</mj-style>
<!-- Dark mode overrides -->
<mj-style>
@media (prefers-color-scheme: dark) {
.light-logo { display: none !important; }
.dark-logo { display: block !important; }
}
</mj-style>
</mj-head>Safe neutrals: (not ) and (not ) — prevents jarring forced inversions.
#121212#000000#F1F1F1#FFFFFFxml
<mj-head>
<mj-raw>
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
</mj-raw>
<!-- Light logo visible by default; dark logo hidden -->
<mj-style inline="inline">
.dark-logo { display: none !important; }
</mj-style>
<!-- Dark mode overrides -->
<mj-style>
@media (prefers-color-scheme: dark) {
.light-logo { display: none !important; }
.dark-logo { display: block !important; }
}
</mj-style>
</mj-head>安全中性色:(而非)和(而非) — 避免刺眼的强制反转效果。
#121212#000000#F1F1F1#FFFFFFAccessibility Checklist
可访问性检查清单
- is set (screen reader email label +
<mj-title>)aria-label - attribute on root
langtag<mjml> - on every
altand<mj-image><mj-social-element> - Heading role set via (NOT as a direct attribute on
mj-html-attributes):mj-textxml<!-- In mj-head --> <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> <!-- On the component --> <mj-text css-class="email-heading" ...>Heading text</mj-text> - 4.5:1 contrast ratio on all text/background pairs
- No text baked into images — always use live blocks
<mj-text>
- 设置(屏幕阅读器邮件标签 +
<mj-title>)aria-label - 根标签上设置
<mjml>属性lang - 每个和
<mj-image>都设置<mj-social-element>属性alt - 通过设置标题角色(而非直接在
mj-html-attributes上设置属性):mj-textxml<!-- In mj-head --> <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> <!-- On the component --> <mj-text css-class="email-heading" ...>Heading text</mj-text> - 所有文本/背景组合的对比度达到4.5:1
- 图片中不能包含文本 — 始终使用可编辑的块
<mj-text>
Component Index
组件索引
Before writing any MJML, read the component file(s) for the components you'll use.
| Group | Components | Load when | File |
|---|---|---|---|
| Head | mj-attributes, mj-font, mj-style, mj-preview, mj-breakpoint, mj-html-attributes | Setting up head, global styles | |
| Layout | mj-body, mj-section, mj-column, mj-group, mj-wrapper | Building structure / grid | |
| Content | mj-text, mj-image, mj-button, mj-divider, mj-spacer, mj-table | Adding content blocks | |
| Interactive | mj-accordion, mj-carousel, mj-social, mj-navbar | Interactive or social elements | |
| Advanced | mj-hero, mj-raw, mj-include | Hero banners, template tags, partials | |
General reference (hierarchy, ending tags, validation, width math, Gmail clip):
mjml-reference.md在编写任何MJML代码前,请先阅读你将使用的组件对应的文件。
| 分组 | 组件 | 加载时机 | 文件 |
|---|---|---|---|
| 头部 | mj-attributes, mj-font, mj-style, mj-preview, mj-breakpoint, mj-html-attributes | 设置头部、全局样式 | |
| 布局 | mj-body, mj-section, mj-column, mj-group, mj-wrapper | 构建结构/网格 | |
| 内容 | mj-text, mj-image, mj-button, mj-divider, mj-spacer, mj-table | 添加内容块 | |
| 交互 | mj-accordion, mj-carousel, mj-social, mj-navbar | 交互或社交元素 | |
| 进阶 | mj-hero, mj-raw, mj-include | 首屏横幅、模板标签、片段 | |
通用参考(层级、闭合标签、验证、宽度计算、Gmail截断):
mjml-reference.mdCompilation
编译
Read for the full workflow. Key command:
compilation.mdbash
npx mjml template.mjml -o dist/template.html --config.minify=true --config.validationLevel=strictHard rules:
- Never
npm install -g mjml - Always use or
npx./node_modules/.bin/mjml - If mjml not in , suggest
package.jsonnpm install -D mjml
完整工作流请查看。核心命令:
compilation.mdbash
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
Examples
示例
assets/examples/basic-layout.mjmlmj-headassets/examples/basic-layout.mjmlmj-headOutput
输出要求
Always deliver:
- — complete MJML source (editable, version-controllable)
<name>.mjml - — compiled output (production-ready, send via ESP)
<name>.html
Name files after the email type: , ,
welcome.mjmlpromo-sale.mjmlorder-confirmation.mjml始终交付以下两个文件:
- — 完整的MJML源文件(可编辑、可版本控制)
<name>.mjml - — 编译后的输出文件(可用于生产环境,通过ESP发送)
<name>.html
根据邮件类型命名文件:、、
welcome.mjmlpromo-sale.mjmlorder-confirmation.mjml