mcpField
E
email-html-mjml

email-html-mjml

github.com/framix-team设计与 UI81955 次安装11 周前更新
代码仓库

关于 email-html-mjml

email-html-mjml 是用于编写 MJML 5.x 响应式邮件模板并编译为 HTML 的技能。它侧重跨邮件客户端兼容、严格验证与无障碍要求,并要求交付源文件和编译文件。

主要功能

  1. 01生成 MJML 5.x 模板
  2. 02编译并验证 HTML
  3. 03提供 Outlook 和 Gmail 兼容指导
  4. 04检查无障碍与深色模式
  5. 05查阅 MJML 组件参考

适用场景

  1. 01制作事务类邮件模板
  2. 02创建促销邮件版式
  3. 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.md
LICENSE
mjml-reference.md
assets/examples/
basic-layout.mjml
newsletter.mjml
order-confirmation.mjml
promo-sale.mjml
assets/examples/partials/
footer.mjml
components/
advanced.md
content.md
head.md
interactive.md
layout.md

详细介绍

email-html-mjml — 响应式邮件开发者

生成有效、兼容不同邮件客户端的 MJML 5.x 模板,并将其编译为可用于生产环境的 HTML。首要目标是兼容性:Outlook(2013–365)、Gmail(网页端/应用)、Apple Mail 和主流移动端客户端。所有输出都必须通过 --config.validationLevel=strict 编译,并能经受 Gmail 的 102KB 截断限制。


工作流程

  1. 收集需求 — 根据用户消息和对话上下文推断邮件类型、品牌颜色和内容。仅在确实缺少且会阻碍进展的信息时提问(例如未提供颜色,但布局中有品牌区块)。切勿一开始就罗列问题。
  2. 规划布局 — 编写代码前决定并说明结构(单栏、双栏网格、主视觉区 + 内容等)。
  3. 加载组件参考 — 编写任何 MJML 前,先阅读下方组件索引中的相关文件
  4. 生成 MJML — 从 <mjml> 开始编写完整、有效的 MJML,并包含完整的 <mj-head>
  5. 编译 — 遵循 compilation.md。使用 --config.minify=true 运行 npx mjml
  6. 交付两个文件 — 始终输出 .mjml 源文件和编译后的 .html 文件

9 条工程规则

  1. 结构完整性 — 所有视觉内容都必须位于 <mj-section> 内的 <mj-column> 中。Section 不能嵌套。
  2. 响应式默认值 — 默认宽度为 600px。对于并排元素(社交栏、Logo 行),使用 <mj-group> 防止在移动端堆叠。使用 <mj-section gutter="..."> 设置列间距,而不是通过 padding 实现。
  3. Outlook 兼容性 — 使用 <mj-font> 设置 Web 字体(防止回退到 Times New Roman)。始终提供回退字体栈(Arial, sans-serif)。对于带背景图片的 <mj-section>,始终同时设置 background-size 和回退用的 background-color。
  4. Gmail 优化 — 自定义 CSS 使用 <mj-style> 上的 inline="inline"。关键样式优先使用组件属性(color、font-size),而不是 CSS 类。
  5. 深色模式 — 仅在用户明确要求,或邮件使用浅色背景、强制反转会造成刺眼效果时,加入深色模式支持。参见下方深色模式模式。
  6. 无障碍访问 — 每个 <mj-image> 都必须设置 alt。始终设置 <mj-title>(用于填充 aria-label)。保持 WCAG 2.1 AA 对比度达到 4.5:1。对于标题角色,使用 mj-html-attributes——在严格验证下,直接在 mj-text 上设置 role/aria-level 属性不合法(参见下方无障碍检查清单)。
  7. 样式效率 — 使用 <mj-attributes> 中的 <mj-all>、组件默认值和 <mj-class>,消除重复的内联样式。
  8. 主视觉区 — 全宽主视觉横幅使用 <mj-hero>;在不支持的客户端中,它会回退为普通 section。避免使用 <mj-accordion> 和 <mj-carousel>——客户端支持太差,实用性不高。
  9. 模板支持 — 普通插值({{firstName}})无需包装——它们会原样保留在文本、属性、mj-title 和 mj-preview 中。只有包含 < 或 > 的块标签({% if x < 5 %}、{{#if a<b}})才需要 `` 保护,否则压缩会静默破坏它们。在列中,内容组件之间的 <mj-raw> 会将其内容输出到 </tr> 和 <tr> 之间,导致标记无效;应将 mj-raw 放在 section 之间,并避免在 <mj-style> 中放置模板标签(参见 compilation.md)。

关键注意事项

MJML 5 默认禁用 mj-include:

  • 除非显式启用 include,否则 <mj-include> 标签会被静默忽略——这是相较于 MJML 4 有意进行的安全更改
  • CLI:添加 --config.allowIncludes true。Node API:传入 ignoreIncludes: false
  • 使用 --config.includePath(CLI)或 includePath(Node)限定允许的目录——仅支持 MJML、HTML 和 CSS include
  • 除非目录已加入允许列表,否则不允许包含位于模板自身目录之外的局部文件
  • --config.validationLevel=strict 无法检测到此问题——被丢弃的 include 仍会以 0 退出,且仍会写入 .html。编译成功并不代表 include 已生效;交付前,请在输出中搜索已知局部文件内容
  • 如果编译后的模板缺少你预期由 include 引入的内容,请先检查这一点

Outlook:

  • 背景图片:仅为 <mj-section> 和 <mj-hero> 生成 VML——其他位置均不会生成
  • 背景定位:仅支持关键字值(top、center、bottom)——像素值会被忽略
  • background-repeat="no-repeat" 始终应与显式设置的 background-size 配对
  • 字体回退:<mj-font> 会通过 MSO 条件注释对 Outlook 隐藏 @font-face

Gmail:

  • 关键布局请使用组件属性——CSS 类可能会被移除
  • 102 KB 截断限制:始终使用 --config.minify=true 编译

iOS / Android 堆叠:

  • MJML 5 的压缩不再移除标签之间的空白字符——htmlnano 会将连续空白字符折叠为一个空格,而 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,该区段中的所有列都必须显式设置此属性

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>

安全的中性色:#121212(而非 #000000)和 #F1F1F1(而非 #FFFFFF)——可避免刺眼的强制反转效果。


无障碍检查清单

  • 已设置 <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 之前,请先阅读你将使用的组件对应的文件。

分组组件何时加载文件
Headmj-attributes, mj-font, mj-style, mj-preview, mj-breakpoint, mj-html-attributes设置 head、全局样式时components/head.md
布局mj-body, mj-section, mj-column, mj-group, mj-wrapper构建结构 / 网格时components/layout.md
内容mj-text, mj-image, mj-button, mj-divider, mj-spacer, mj-table添加内容块时components/content.md
交互mj-accordion, mj-carousel, mj-social, mj-navbar添加交互或社交元素时components/interactive.md
高级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

示例

在 MJML 5.4.0 上,以下四个示例均可在 --config.validationLevel=strict --config.minify=true 下成功编译。

文件参考用途
assets/examples/basic-layout.mjml仅供参考结构。MJML 文档中的示例:包含 6 个区块的布局(页眉、图片主视觉 + 按钮、简介、双列图片 + 文本、三列图标、社交媒体行)。刻意保持精简——没有 mj-head、深色模式或实际文案,只有占位文案。不是生产模板。
assets/examples/order-confirmation.mjml交易类邮件。完整的 mj-head(mj-attributes + mj-class + mj-font + mj-html-attributes)、带有 scope="col" 表头的收据 mj-table、在 mj-raw 中使用 Handlebars 并配有 htmlmin:ignore、条件区块,以及通过 mj-include 引入 partials/footer.mjml。需要 --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 和品牌都是占位内容——请替换,不要原样发布。


输出

始终交付:

  1. <name>.mjml — 完整的 MJML 源码(可编辑、可纳入版本控制)
  2. <name>.html — 编译后的输出(可用于生产环境,通过 ESP 发送)

文件名应根据邮件类型命名:welcome.mjml、promo-sale.mjml、order-confirmation.mjml

评论

支持 Markdown