1.1 支持Outlook
以下是你需要了解的内容,以使你的HTML电子邮件在Windows上的Outlook中轻松工作:
1.1.1 Outlook 渲染引擎的工作原理
自2007年以来,Outlooks on Windows一直使用Word作为HTML和CSS的渲染引擎。微软在2009年证明了使用Word的合理性:
我们决定继续使用 Word 创建电子邮件,因为我们相信这是最好的电子邮件创作体验,我们的 Word 客户已经享受了超过 25 年的丰富工具。
Word不仅不适合渲染HTML和CSS,而且关于这个问题的文档也很少。关于Word渲染的唯一官方现有文档是Microsoft在2006年发布的一篇文章,解释了Outlook 2007中的HTML和CSS渲染功能。
它包括以下方面的信息:
- CORE:
color
,background-color
, 文本属性 (font
,font-family
,font-style
,font-size
,font-weight
,text-decoration
,text-align
,vertical-align
,letter-spacing
,line-height
,white-space
), border shorthand properties (border
,border-color
,border-style
,border-width
,border-collapse
) 和其他一些属性. - COREEXTENDED:
text-indent
和margin属性 (margin
,margin-left
,margin-right
,margin-top
,margin-bottom
). - FULL:
width
,height
,padding
(以及padding-left
,padding-right
,padding-top
,padding-bottom
) 和border longhand 属性(border-left
,border-left-color
,border-left-width
,border-left-style
, 等等).
这些类别中的每一个都仅适用于某些 HTML 元素:
- <body> 和<span> 仅支持 CORE 属性.
- <div> 和<p> CORE 和COREEXTENDED 属性都支持.
- Outlook支持的所有其他元素 (像<table>, <td>, <h1>, <ul>, <li>, 等等) 都支持CORE, COREEXTENDED 和FULL 属性。
这意味着我们必须考虑使用哪个元素来应用某些样式。因此,如果我们必须在一个通用的容器元素上定义一个宽度或高度,我们将使用<table>。如果我们需要内边距,我们也会使用<table>和<td>。
直到今天,Windows上的Outlooks是我们在HTML邮件中仍然使用表格的唯一原因。幸运的是,我们有办法只让这些表格在Outlook上可见,而在能力更强的电子邮件客户端隐藏这些表格,让我们使用更多的语义代码。
1.1.2 条件注释
微软早在1999年就在Internet Explorer 5中引入了条件注释。在IE6-9时代,它们在网络上相当流行,但在Internet Explorer 10和11中被取消了。它是这样工作的:在一个普通的HTML注释(<!---->)内,你可以编码一个条件,如果该条件得到满足,相应的内容就会变得可见。下面是一个例子:
<!--[if IE]>
<p>This is only visible in Internet Explorer.</p>
<![endif]-->
事实证明,在使用Word渲染引擎的Windows版Outlook中也支持条件注释。我们将使用mso关键字,而不是使用IE作为条件:
<!--[if mso]>
<p>This is only visible in Outlook 2007 and above on Windows.</p>
<![endif]-->
条件也可以与版本号联系在一起。例如,mso 12针对Outlook 2007。不幸的是,微软已经停止在最新的Outlook版本中递增这个版本号。所以mso 16同时针对Outlook 2016和Outlook 2019。
我们还可以使用操作符,如gte(大于或等于)或lte(小于或等于)来创建更复杂的条件:
<!--[if gte mso 12]>
<p>This is visible in Outlook 2007 and above.</p>
<![endif]-->
另一个有用的操作符是NOT操作符(!),它可以让我们为除了Windows上的Outlook之外的电子邮件客户端插入代码:
<!--[if !mso]><!-->
<p>This is visible in every email client except the Outlooks on Windows.</p>
<!--<![endif]-->
1.1.3 mso-属性
Windows上的Outlook有数百个专有的CSS属性,大部分都是通过"mso-"前缀来识别的。
对于很多标准的CSS属性,微软有一个相应的专有版本,前缀为 "mso-",后缀为"-alt"。例如,我们可以用 "mso-padding-alt "属性为Windows上的Outlook定义一个内边距值。经常使用的一种方式是在给按钮编码时。理想情况下,一个按钮的整个可见区域应该是可点击的,所以通常会给<a>元素添加内边距。但是Outlook在Windows上不支持这个。因此,用<table>来包装每个"<a>"元素,并使用 "mso-padding-alt "属性来应用仅适用于Windows上的Outlook的内边距:
<table border="0" cellpadding="0" cellspacing="0" role="presentation" align="center" style="margin:0 auto; max-width:100%; background:#2ea44f; border-radius:5px; border-collapse:separate;" class="email-btn">
<tr>
<td style="mso-padding-alt:14px 16px; text-align:center;">
<a style="padding:14px 16px; display:block; min-width:128px; color:#fff; font:bold 16px/20px Helvetica Neue, Roboto, sans-serif; text-decoration:none; text-align:center;" href="https://www.example.com" target="_blank" >Call to Action</a>
</td>
</tr>
</table>
Outlook也有其他不加前缀的专有属性,可以模仿更现代的CSS属性。例如,Outlook中的text-underline-color与CSS中的text-decoration-color相同。因此,如果你想给文本下划线应用一个特定的颜色,你可以使用这两个属性:
text-underline-color: red; /* Outlook version */
text-decoration-color: red; /* Standard version for clients that supports it */
Stig Morten Myre有一篇很好的文章(https://cm.engineering/fixing-bugs-with-outlook-specific-css-f4b8ae5be4f4),解释了如何用Outlook特定的CSS修复错误,包括如何使用mso-text-raise或 mso-line-height-rule: exactly 的提示。
1.1.4 VML
VML是SVG的祖先,由微软在九十年代末精心打造。就像SVG一样,你可以用标记代码绘制内容。例如,如果我们想画一个红色的矩形,我们可以使用<v:rect>元素和以下代码:
<v:rect xmlns:v="urn:schemas-microsoft-com:vml"
fillcolor="red"
stroked="false"
style="width:200px; height:100px;">
</v:rect>
让VML在Windows的Outlook中工作的前提条件是添加其命名空间声明(xmlns:v="urn:schemas-microsoft-com:vml")。它可以为我们使用的每个 VML 元素以inline方式重复,也可以只在<html>元素中添加一次。因为VML只在Windows的Outlook中工作,所以我们要确保把它包裹在一个条件注释中。下面是我们之前的红色矩形的一个完整的工作例子:
<!DOCTYPE html>
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<title>VML rectangle</title>
</head>
<body>
<!--[if mso]>
<v:rect fillcolor="red" stroked="false" style="width:200px; height:100px;"></v:rect>
<![endif]-->
</body>
</html>
当然,我们可以做比红色矩形更令人兴奋的事情。我们可以使用VML的一个方法是实现Windows上Outlook不支持的属性--例如背景图像。如果我们想在我们的<body>元素上显示一个背景图像,我们可以使用<v:background>元素(Using the Background Element - Win32 apps | Microsoft Learn)。然而,这可能是一个辅助功能问题的来源,因为它将其中的内容变成了VML图像的一部分,这可能会让屏幕阅读器等辅助技术丢失这些内容。
微软的《如何在网页上使用VML》(How to Use VML on Webpages - Win32 apps | Microsoft Learn)和《VML对象模型参考》(VML Object Model Reference - Win32 apps | Microsoft Learn)是开始学习VML的好地方。
1.1.5 以120dpi渲染
在某些Windows配置上,Windows上的Outlook对邮件应用DPI缩放。电子邮件开发人员Courtney Fantinato有一个详细的指南(Correcting Outlook DPI Scaling Issues - Courtney FantinatoCourtney Fantinato)来纠正Outlook的DPI缩放问题。以下是你需要遵循的三个规则:
1. 在<html>元素上添加Microsoft Office命名空间
<html xmlns:o="urn:schemas-microsoft-com:office:office">
2. 在<head>元素内添加以下OfficeDocumentSettings声明
<!--[if mso]>
<xml>
<o:OfficeDocumentSettings>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
<![endif]-->
3. 始终使用在CSS中定义的尺寸而不是HTML属性
<!-- Bad example -->
<table align="center" role="presentation" width="600">…</table>
<!-- Good example -->
<table align="center" role="presentation" style="width:600px;">…</table>
这方面唯一的例外是图像。在Windows的Outlook中,在样式属性中设置的宽度在图像上是被忽略的。
1.2 让你的电子邮件在没有<style>的情况下工作
当涉及到将样式应用到任何HTML内容(无论是网页还是HTML电子邮件)时,有三种方法可以做到,使用:
- 一个<link>元素和一个外部样式表
- 一个<style>元素
- 一个内联style属性
电子邮件客户端对这些技术的支持可能会有很大的不同。这通常是由于安全问题造成的。电子邮件客户端需要对他们所允许的样式非常谨慎,因为恶意的电子邮件可以使用样式来欺骗用户。例如,恶意的电子邮件开发者可以使用固定或绝对定位在电子邮件客户端自己的界面上堆叠虚假的元素。
电子邮件客户端采用了各种方法来解决这个问题,例如只允许从他们自己的安全列表中选择一个属性或值的子集。他们还对HTML邮件中的CSS选择器进行前缀处理,以防止邮件样式影响到客户端的界面。例如,像.button {}这样的选择器在Outlook.com中会变成.rps_1234 .x_button {}。
<link>元素在桌面原生应用程序中得到了很好的支持,如苹果邮件(在macOS或iOS上)或Outlook(在Windows或macOS上)。然而,它几乎被网络邮件客户端(如Gmail、Outlook.com、Yahoo Mail等)以及许多移动应用程序(如iOS或Android上的Gmail、Outlook或Yahoo Mail)普遍忽视。因此,这不是一种推荐的HTML邮件风格的方式。
<style>元素有更好的支持。但它也有一些怪癖。特别是Gmail客户端,只支持在<head>中定义的style标签(而不是在<body>中)。他们对任何语法错误也非常挑剔,Gmail会删除整个<style>,其中包含它不喜欢的东西(例如,@声明中的@)。在HTML邮件中使用多个<style>元素是一种常见的做法。在删除不支持的元素后,Gmail会将它们合并成一个限制在16KB的单一元素。
但<style>元素并不总是受支持。例如,如果您在 Gmail 应用(在 iOS 或 Android 上)收到一封包含非 Gmail 地址(如 Outlook.com 或 Yahoo 地址)的电子邮件,将无法获得<style>支持。
<style>元素也可以在上下文中被删除。例如,当你在Gmail的桌面网络邮件中转发一封邮件时,所有<style>标签都会被删除。当一封电子邮件以其未剪辑的(unclipped)版本被浏览时,Gmail也会删除<style>标签。
因此,作为一般规则,通过HTML style属性使用内联样式更安全、更稳健。我们也可以使用<style>标签,但只是作为一种渐进式的改进,特别是对于像@media查询或:hover伪类这样不能内联的东西。
在没有<style>元素的情况下,"使电子邮件工作 "可以意味着很多不同的事情。但最好首先考虑以下几点:
- 布局。一封没有<style>的邮件应该在没有水平滚动的情况下调整到任何宽度。我通常考虑低至280px宽,这反映了在iPhone SE上用Gmail查看邮件的宽度。
- 品牌。一封没有<style>的邮件应该反映发件人的品牌。
1.3 避免自动链接
电子邮件客户端会自动添加指向某些关键字的链接。以下类型的文本可能会发生这种情况:
- URLs (sitepoint.com, https://www.sitepoint.com/blog/)
- 电子邮件地址 (support@sitepoint.com)
- 电话号码
- 通信地址
- 日期
- 航班号
下图显示了当点击当前航班号时,Apple Mail如何提供详细的航空航班信息。
问题是,如果我们不对它们进行规划,这些链接将以其默认的样式出现(通常是蓝色和下划线)--这可能会产生意想不到的、不受欢迎的效果。例如,在一个已经是蓝色的背景上,一个自动的蓝色链接将是不可读的。不幸的是,预测这些自动链接并不是万无一失的。
以下是避免自动链接的三种可能方法:
1. 为Apple Mail添加一个特定的meta声明。在我们邮件的<head>中加入这个标签,Apple Mail就不会自动添加链接:
<meta name="format-detection" content="telephone=no, date=no, address=no, email=no, url=no">
2. 使用一个零宽度的非连接符。零宽度非连接符是一个看不见的字符,在HTML中由实体‌(或͏)表示。我们将在这里使用它来破坏电子邮件客户的内容检测算法,把它放在可能添加链接的文本中间。
Visit Sitepoint‌.com for more details!
3. 自己添加链接。电子邮件客户端足够聪明,不会尝试添加指向已链接的文本的链接。因此,如果我们自己在我们知道可能会自动链接的文本周围添加一个链接,我们可以应用自己的样式。链接仍然存在,但至少不会那么明显可见:
Visit <a href="https://sitepoint.com" style="color:#000; text-decoration:none;">sitepoint.com</a> for more details!
1.4 使用真实的URLs
微软的Outlook.com网络邮件在使用非URL文本作为<a>元素的href值时有一个错误。例如:
<a href="" style="color:blue;">Get the app on iOS</a><br>
<a href="TBD" style="color:green;">Get the app on Android</a>
这被Outlook.com转化为以下内容:
Get the app on iOS<br>
[TBD] Get the app on Android
整个 <a> 元素,包括其样式,都被删除。href属性的值(如果它不是空的)被添加到链接文本之前的括号中。
1.5 添加一个空的<head>元素
Android上的雅虎邮箱会删除任何邮件的<head>元素。这是很不方便的,因为这意味着<style>标签,以及媒体查询,不能在那里工作。但人们发现,雅虎邮箱应用只对邮件的第一个<head>做这事。
因此,这意味着,如果我们在代码中先包含一个假的空的<head>,然后保留我们正常的<head>元素,Android上的Yahoo Mail将正确地保留它并解释它。
<!DOCTYPE html>
<html lang="en">
<head></head>
<head>
<title>My Email</title>
<style>
@media (max-width: 600px) {
…
}
</style>
</head>
下面的图片显示了安卓系统上雅虎邮箱应用中的一个电子邮件例子(Really Good Emails 由Really Good Emails提供)。如果没有双<head>,该邮件会被客户端自动缩放。有了这个修正,电子邮件就会像预期的那样显示媒体查询。
1.6 将电子邮件的大小保持在102KB以下
Gmail的桌面网络邮件有一个臭名昭著的门槛,即102KB,超过这个门槛,它就会截断一封HTML邮件,并显示一个"[信息被剪断]"的提示,以及一个 "查看整个信息 "的链接。虽然不知道为什么会有这个限制,也不知道为什么会在这样一个奇怪的数字上,但多年来它一直如此。
这 102KB 的限制仅考虑我们电子邮件的 HTML 大小。它不包括电子邮件的其他部分(如纯文本版本,或所有的MIME头字段)。它也不包括任何远距离资产如图像或字体的大小。因此,如果我们的HTML大小为40KB,图片为500KB,我们就没有问题。
我们想避免这个阈值,因为:
- Gmail会在102KB处截断我们的邮件以插入它的"[信息被剪断]"提示,即使这是在<table>的正中间。这很可能会以意想不到的方式破坏我们的电子邮件。
- 在 "查看整个邮件 "的链接后面,Gmail将提供对HTML和CSS的低级支持。例如,任何<style>标签(以及媒体查询)在这个视图中会被删除。
衡量这一点的基本方法是看我们的HTML文件在操作系统中的大小
请记住,一些电子邮件服务提供商可能也会对我们的HTML的部分内容进行处理,使邮件大小增加。例如,CSS内联或链接跟踪可能是使我们的代码超重的原因。
- 优化我们的HTML电子邮件代码可以通过几种方式进行。以下是通常认为最重要的步骤:
- 将你的代码最小化。但不要使用专为Web构建的工具!
- 删除未使用的代码。如果你的邮件是由一个通用的模板建立的,其中包括很多不同组件的样式,你可能最终会发现你实际上并没有使用的样式。
- 注意CSS内联。如果你有一个针对通用选择器的 CSS 规则(例如,* { color:#000; }),这将应用于代码中的每个 HTML 元素(包括 <tr>、 <br>和其他大量无用的地方)。确保你的 CSS 内联按预期工作,并在内联样式后检查你的代码。
- 少用表格。表格对于Windows上的Outlook是必要的,但它们可能很重。如果我们不使用内边距、边框或多列,那么简单地让更多的语义位的代码堆叠在一起,可能会更好、更轻。
Gmail也可以显示"[信息被剪掉]"的提示,但并不真正剪掉你的信息。这可能是由于在我们的信息中存在像©这样的特殊字符造成的。
1.7 删除CSS注释
雅虎和AOL客户端对CSS注释有一个特殊的错误。例如,考虑下面的代码
<style>
/* Big title */
.title {
font-size: 32px;
}
</style>
这被雅虎和AOL转化为以下内容:
<style>
#yiv1234567890
#yiv1234567890 .yiv1234567890title {
font-size: 32px;
}
</style>
电子邮件客户端通过添加一个自定义的前缀(yiv1234567890)来重命名每个类,并在每个选择器上添加一个前缀(#yiv1234567890)。这是整个电子邮件客户端--特别是webmail版本--非常普遍的做法,需要确保我们的电子邮件样式不能影响webmail客户端自己的样式,反之亦然。
这里的错误是,雅虎也试图将其前缀添加到CSS注释中。而由于它只在一行代码中单独添加,这意味着它适用于下一行的CSS选择器。考虑一下下面这个选择器:
#yiv1234567890 .yiv1234567890title { }
现在得到的解释如下
#yiv1234567890 #yiv1234567890 .yiv1234567890title { }
如果我们在CSS规则内(大括号之间)有CSS注释,则此错误不适用。但作为一般的警告规则,最好在发送电子邮件之前删除所有CSS注释。
1.8 使用HTML5 Doctype
电子邮件客户端不会原封不动地输出您的HTML电子邮件代码。他们会进行各种转换,例如过滤不需要的标签(如<script>)、属性和样式。尤其是网络邮件客户端不会保留你的整个HTML。
一封网络邮件被显示在一个网页中,这个网页已经有自己的doctype,<head>和<body>,以及其他元元素。因此,像Gmail这样的网络邮件客户端会在你的头部寻找<style>标签,将它们编译成一个标签,并保留你的<body>元素的内容。
这意味着,在很多情况下,你最终会使用网络邮件的doctype,而不是你的。而现在,大多数网络邮件客户端都使用HTML5 doctype:
<!DOCTYPE html>
HTML5 doctype的一个副作用是,<img>元素下面有一个行距。当你对图片进行分割时,这一点会变得很明显。
下面的图片展示了当你忘记在HTML邮件中的图片上设置display:block时会发生什么。
有各种解决方案可以解决这个问题。以下是三个:
- 在<img>元素的内联样式中添加 vertical-align:middle。(如果你需要对文本和图像进行不同的对齐,这可能会影响周围的文本)。
- 在<img>元素的内联样式中添加 display:block。(这改变了内容的流向,可能会影响到同级别的元素)。
- 给<img>的父元素添加font-size:0。(这可能会影响替代文本的渲染)。
下面是第一个解决方案的例子,它适用于一个带有内联style属性的图像
<img src="logo.png"
alt=""
style="vertical-align:middle;" />
1.9 结论
处理电子邮件客户端的古怪问题是电子邮件开发人员工作的一部分。关注电子邮件开发者社区是一个好主意,可以跟踪最新的更新和实践。
这是一个好消息,因为这可以为互动等更有趣和令人兴奋的功能开辟道路!在下一章中,我们将了解如何通过CSS和HTML使电子邮件更具交互性。