主流邮件客户端对嵌套深度容忍度低,outlook通常在第4层开始丢弃子元素;标签和外部css基本失效,仅内联style属性被广泛支持;juice内联需注意webresources、媒体查询处理及url路径;javascript和交互动效全面禁用,字体回退链逗号须为英文半角。

邮件客户端对 <div> 嵌套深度的实际容忍度
<p>绝大多数主流邮件客户端(Outlook、Apple Mail、Gmail App)不支持超过 3–4 层的 <code><div> 嵌套,尤其 Outlook(基于 Word 渲染引擎)会直接截断或忽略深层嵌套内容。这不是规范限制,而是渲染器实现缺陷。
<ul><li>Outlook 2016/2019/365:通常在第 4 层 <code><div> 开始丢弃子元素,<code><div><div><div><div>…</div></div></div></div> 中最内层可能完全不显示
<table> 和 <code><div>,仍可能触发样式重置
<li>Apple Mail 对嵌套本身较宽容,但若某层 <code><div> 含 <code>display: flex 或 float,整层会被忽略
解决方案不是“尽量少嵌套”,而是「用 <table> 替代布局型 <code><div>」——所有邮件模板引擎(MJML、Foundation for Emails、Cerberus)默认都这么做,因为 <code><table> 的单元格嵌套是被全平台稳定支持的。
<h3>
<code>style 标签和外部 CSS 在邮件中为何基本失效
90% 的邮件客户端会剥离 <style></style> 标签或忽略其中的类选择器。Gmail 会移除整个 <style></style> 块;Outlook 完全不解析 CSS 类;iOS Mail 虽保留部分 <style></style>,但仅支持极少数属性(如 color、font-family),且不支持媒体查询。
- 唯一被广泛支持的写法是内联
style属性:<p style="margin:0; font-size:14px;"></p> -
!important在 Outlook 和 Gmail 中多数被忽略,不要依赖 - 伪类(
:hover、::before)在所有主流客户端均无效 - MJML 编译后自动内联,但需确认其
inline-css插件已启用且未被自定义配置禁用
注意:某些模板引擎(如 Handlebars + custom inliner)若未调用 CSS 内联工具(如 juice 或 premailer),生成的 HTML 仍含外部引用,发出去就是白屏或无样式。
使用 juice 内联时容易漏掉的三个关键点
juice 是 Node.js 场景下最常用的内联工具,但它默认行为与邮件需求存在错位,不手动调整就会出问题。
- 默认不处理
<link rel="stylesheet">—— 必须显式传入{ webResources: true }并确保 CSS 文件路径可访问 - 遇到
@media查询会直接跳过整条规则,导致响应式断点丢失;需提前用css-media-query工具将媒体查询展开为内联条件(如用postcss-preset-env+postcss-inline-rem预处理) - 对
background-image的 URL 不做路径补全,若 CSS 中写的是url(images/bg.png),而 HTML 在根目录,内联后会变成 404;建议统一用绝对 URL 或预处理为 base64
示例错误写法:juice(html, { applyStyleTags: true }) —— 缺少 removeStyleTags: true,会导致原始 <style></style> 未被清除,与内联样式冲突。
复杂组件(如轮播、折叠菜单)在邮件里根本不能用
JavaScript 全面被禁用,onclick、onload、data- 属性无执行能力;CSS 动画、transform、visibility: hidden 切换等交互逻辑在 99% 客户端中无效。所谓“交互动效邮件”实际只靠 GIF 或多状态静态图模拟。
- 轮播图:只能用单帧 GIF 或拼接多图的
<img src="carousel.gif">,无法控制暂停/跳转 - 折叠区块:无法用
details/summary或 JS toggle,只能做成“展开版”和“精简版”两个独立模板,由收件人自行选择订阅偏好 - 表单提交:
<form></form>标签会被 Outlook 删除,按钮点击只能指向mailto:或预设参数的 URL(如https://example.com/subscribe?email={{email}})
真正容易被忽略的,是字体回退链中 font-family 的逗号分隔必须用英文半角,且不能有空格——style="font-family: 'Helvetica Neue', Arial, sans-serif;" 是安全的,但 style="font-family: 'Helvetica Neue' , Arial , sans-serif ;" 在部分 Android 客户端会导致整个声明失效。











