如何修复Outlook黑暗模式的问题(邮件设计)

926 阅读16分钟

如果你曾经为黑暗模式建立了一个HTML电子邮件,那么Outlook for Windows中不可预测的文本颜色变化无疑是你所遇到的许多令人费解的问题之一。

Outlook在黑暗模式下粗暴地颠倒了颜色,在某些情况下甚至把深色变成白色。这不仅会导致你的邮件中出现非常难看的部分,还可能导致文本完全无法辨认。

本教程将告诉你如何修复Outlook的一些最糟糕的行为,当它涉及到黑暗模式下的文本颜色。

Microsoft Outlook有许多版本。当我在本文中提到 "Outlook "时,我指的是Windows版的Outlook的Microsoft 365版本。

下一步

  • 在本教程的第一部分,我们将看看只使用HTML和CSS的颜色样式的文本的颜色变化。
  • 第二部分将讨论VML(矢量标记语言)形状内的文本颜色变化。

1.简单彩色文本的颜色变化

假设你有一个中等绿色的区域,上面有一些大的白色文字,像这样。身体上有深色的文字,而绿色则要淡得多。

然而,在Outlook黑暗模式下,随着颜色的切换,即使标题的背景几乎没有被调整,文本也几乎变成了黑色。虽然大多数用户仍然可以阅读它,但这并不是你要的效果。你希望它是白色的。

解决方案。在你的文本中应用微软文本梯度

微软的Word渲染引擎是微软Outlook中电子邮件渲染的动力。如果你使用过Word,你会知道你可以用很多不同的方式来设计你的文本,其中之一就是添加一个梯度。

这些渐变也在Outlook中呈现,这很好,但它们在黑暗模式中被剥夺了。如果你想使用多种颜色的实际梯度,这是不幸的,但对于在黑暗模式下修复文本问题来说,这是一个好消息,因为它为我们提供了一种分别控制光明模式和黑暗模式的方法。

如果我们创建一个由单一颜色组成的 "渐变",我们可以将其应用于我们的文本,它将在 "光照模式 "下显示。

在黑暗模式下,渐变被剥离,显示出在你的文本上设置的后备color 。然后,Outlook将根据其黑暗模式的算法处理备用颜色,通过加深或颠倒它,就像对待任何正常的文本颜色一样。

这意味着我们确实需要变得有点棘手,并确保我们选择的后备颜色将变成我们在Outlook黑暗模式中想要的颜色。但是,一旦我们弄清楚了这一点,我们就可以完全控制我们的文本在两种模式下的外观。

在浅色模式下,渐变色将在文本颜色的顶部可见。在黑暗模式下,它将被丢弃,Outlook将倒置后退的颜色。

如何实现MSO梯度解决方案

首先,确定你需要修复的代码。在这种情况下,我正在修复一段我想保持白色的文本。

给你要修复的代码添加一个类。在这里,我想确保我的文本在黑暗模式下保持白色,所以我使用了.keep-white

记住,Outlook不会尊重元素上的多个类,所以要确保这是你的元素上唯一的类。如果它已经应用了一个类,请使用该类,或找到其他方法来定位该元素。

<p class="keep-white" style="color:#ffffff;">This text will remain WHITE</p>

接下来,到你的文件的head ,添加这个条件代码,里面有一个样式块,包含一个带有你的新类名称的CSS规则。

<!--[if gte mso 16]>
    <style>
        .keep-white {}
    </style>
<![endif]-->

条件注释将限制这段代码的可见性,使其适用于大于等于"mso 16"的微软Outlook版本,这实际上是针对Outlook 2016和更新的版本,这包括我们所针对的微软365版本。

包括在这一堆中的旧客户端(如Outlook 2016)仍然会在浅色模式下应用渐变,这看起来是正确的,他们没有暗色模式,所以在这方面不会发生什么。那么,为什么不直接将这段代码应用于所有版本的Outlook呢?好吧,我发现旧版本,如Outlook 2007,不能正确应用梯度。相反,他们会显示回退的颜色,如果在浅色模式下显示,这看起来并不好。把它限制为gte mso 16,就可以很好地避免这个问题。

获得梯度代码

现在我们需要Light Mode单色渐变的CSS。如果你只需要黑色和白色,你可以使用这些片段。

黑色。

mso-style-textfill-type:gradient;
mso-style-textfill-fill-gradientfill-stoplist:"0 \#000000 1 100000\,99000 \#000000 1 100000";

白色。

mso-style-textfill-type:gradient;
mso-style-textfill-fill-gradientfill-stoplist:"0 \#FFFFFF 0 100000\,100000 \#FFFFFF 0 100000";

对于其他颜色,你可能会有一些运气,只需替换其中的一些十六进制值。然而,停止列表的结构有点玄乎,因为它是由Open Office XML(OOXML)标准衍生出来的,用于绘制带有渐变填充的形状。作为一个例子,这里有一个紫色渐变的CSS。

mso-style-textfill-type: gradient;
mso-style-textfill-fill-gradientfill-stoplist: "0 \#7030A0 -1 100000\,99000 \#7030A0 -1 100000";

你可以查看该规范以了解更多信息,并由此手动生成你自己的梯度CSS。

不过,这不是很直观,坦率地说,如果你能使用Microsoft Word,还有一个更简单的方法:让它为你做艰苦的工作,并窃取生成的CSS代码。方法是这样的。

  1. 打开Microsoft Word
  2. 打出几个字
  3. 进入 "**格式">"文本效果"(Mac)**或点击功能区的 "文本颜色 "图标,然后进入 "渐变">"更多渐变"(Mac和Windows)
  4. 在那里,你可以设置一个有两个相同颜色停顿的渐变(这里我将使用白色)。
  5. 完成后,将你的文件保存为 "网页"(扩展名为.htm或.html)。
  6. 在你的代码编辑器中打开HTML文件,一直滚动到底部,找到你打出的字,这些字将被包裹在一个paragraphspan 标签中,其中包含我们想要的CSS代码。

该CSS将看起来像这样。

<p class=MsoNormal><b><span lang=EN-GB style='font-size:22.0pt;line-height:120%;mso-style-textfill-type:gradient;mso-style-textfill-fill-gradientfill-shadetype:linear;mso-style-textfill-fill-gradientfill-shade-linearshade-angle:5400000;
mso-style-textfill-fill-gradientfill-shade-linearshade-fscaled:no;mso-style-textfill-fill-gradientfill-stoplist:"0 \#FFFFFF 0 100000\,100000 \#FFFFFF 0 100000"'>Hello, here is some text.<o:p></o:p></span></b></p>

我发现你只需要其中的两个部分,首先是指定我们想要一个渐变的那一行。

mso-style-textfill-type:gradient;

和颜色停止列表。

mso-style-textfill-fill-gradientfill-stoplist:"0 \#FFFFFF 0 100000\,100000 \#FFFFFF 0 100000";

一旦你有了第一行和停止列表,就把它们添加到你的CSS规则中,这样它看起来就像这样。

<!--[if gte mso 16]>
    <style>
        .keep-white {
            mso-style-textfill-type:gradient;
            mso-style-textfill-fill-gradientfill-stoplist:"0 \#FFFFFF 0 100000\,100000 \#FFFFFF 0 100000";
        }
    </style>
<![endif]-->

我们已经设置了我们的渐变,这就是在灯光模式下的显示。

现在该是解决我们问题的时候了:添加我们的后备颜色。

正如我们在上面看到的,在黑暗模式下,Outlook将放弃渐变,读取后备颜色,然后像通常那样调整或反转。这意味着我们需要选择一种颜色,让Outlook在黑暗模式下将其变成我们想要的颜色。

由于我想要白色,这很容易:Outlook黑暗模式完全颠倒了黑白,所以我只需要把回退颜色变成黑色。

我将把我的回退color 值添加到CSS规则中,并添加!important ,以确保它覆盖我在段落标签上的内联样式,即在所有其他客户端将文本设置为白色。我的规则现在看起来像这样。

<!--[if gte mso 16]>
    <style>
        .keep-white {
            mso-style-textfill-type:gradient;
            mso-style-textfill-fill-gradientfill-stoplist:"0 \#FFFFFF 0 100000\,100000 \#FFFFFF 0 100000";
            color:#000000 !important;
        }
    </style>
<![endif]-->

就这样了当我发送一个测试时,我现在看到我的文本在Microsoft 365 Outlook中保持白色,无论我是使用浅色模式还是深色模式。

关于使用彩色文本的说明

正如你在上面的步骤中所看到的,在Word中为浅色模式生成梯度很容易。找到正确的后备颜色才是棘手的,因为很难预测Outlook是要反转一个颜色还是在黑暗模式下只是变暗。

然而,通过一点试验和错误,你可以得到你需要的结果。发送一些颜色样本给Outlook,以确定在黑暗模式下的正确色调,这可能会有帮助。然后,你可以使用在黑暗模式下产生的任何十六进制颜色,并将其作为你的后备方案。

2.修复VML中的文本颜色变化

如果你使用过VML和Outlook黑暗模式,你就不会对各种问题感到陌生。最恼人的问题是,在黑暗模式下,VML的填充物和图像不会被调整,但文本颜色会被调整,这可能导致像这样完全无法辨认的文本。

在浅色模式下,文本是可见的,但在深色模式下,文本已经变成了非常暗的灰色,使其无法辨认。

不幸的是,当涉及到黑暗模式时,VML块内的文本往往表现得与普通文本不同,所以上面的修复在VML内不能可靠地工作。

其主要原因是一些非常奇怪的事情;似乎有两种不同的黑暗模式算法在Outlook 365的不同副本中运行。

我观察到Litmus提供的Outlook 365的版本与Email on Acid、Testi和我自己的Windows 10电脑的版本完全不同。

奇怪的是,当你使用上面的梯度技巧时,Litmus的版本并没有反转回退的颜色,它只是按原样显示。

由于最新的Outlook显然有不同的副本在流通,它们会做两件完全不同的事情,这不再是我们问题的一个可行的解决方案。

文本填充的问题

这种差异似乎也解释了为什么另一个流行的技巧,试图修复Outlook中的文本,似乎对一些电子邮件开发人员有效,而对另一些人无效。

一个流行的建议是使用,例如,mso-style-textfill-fill-color:#000000; ,以确保文本在黑暗模式下保持黑色。

这种纯文本填充的方式在黑暗模式下不会像梯度那样被剥离,但是在Outlook的不同副本中,它在VML中的解释也存在一些重大的差异。

正如你在下面看到的,当一个黑色的文本填充被应用在一个白色的VML填充上时,所有的Outlook副本在黑暗模式下都显示为浅灰色。

然而,当你在黑色VML形状上使用白色文本填充时,在Acid、Testi和我自己的电脑上的Email中,它实际上显示为非常深的灰色,而在Litmus则显示为浅灰色。

同样的,在VML上的彩色文本填充,在Acid、Testi和我的机器上显示的是(大部分)深色文本填充的趋势,而在Litmus的版本则倾向于变浅和去饱和。

遗憾的是,我不知道这里到底发生了什么,但至少我们知道,当涉及到修复VML内部的黑暗模式文本问题时,我们可以完全排除mso-style-textfill-type:gradientmso-style-textfill-fill-color

绕过这一切的方法

避免VML内部和外部文本行为差异的一个方法是使用CSS定位和z-index,将你的电子邮件内容分层在你的VML内容之上,使你的文本内容与VML分开。如果这对你来说是可行的,那么它将意味着你避免了文本被区别对待,而我们在第一部分中看到的mso-style-textfill-type:gradient 技巧将为你完美地工作。

然而,这并不总是可能的,那么还有什么可以做的呢?

一个针对VML内部的实验性解决方案:利用color:auto;的力量

在对许多不同的Word生成的HTML文件进行挖掘的过程中,我注意到有几个颜色值经常出现,如color:window;color:windowText;color:auto; 。在对它们进行玩耍之后,我对许多其他的颜色值没有什么好感,但是,auto 实际上似乎有自动计算颜色的能力,而且事实证明,你可以在VML中使用它来确保你的文本渲染为黑色或白色,在黑暗和光明模式之间完全没有变化。

它的计算似乎是基于主体背景+VML填充色的组合。(其他布局或包装元素应用了自己的背景色,似乎对计算没有任何进一步的影响)。如果你有一个深色的主体背景和一个浅色的VML填充,那么color:auto; ,就会变成黑色或一个非常深的灰色。如果你有一个浅色的主体背景和一个深色的VML填充,那么color:auto; ,就会解析为白色或非常淡的灰色。

作为一个一般的指导,灰度的临界点似乎如下。

如果你需要白色文本

  • 主体背景必须是**#555555或更浅的**颜色
  • VML填充必须是**#333333或更深的颜色**

如果你需要黑色文本

  • 主体背景必须是**#444444或更深的颜色**
  • VML填充必须是**#555555或**更浅的颜色

你能在同一封邮件中解决这两个问题吗?

一句话:不能。在大多数情况下,你只能解决布局中的黑色或白色文本元素,而不能同时解决,因为color:auto; 部分是根据你的正文背景颜色计算出来的,这显然是全局的。你可以自由地进行试验,因为你可能会有更好的运气,但如果你在整个邮件中有很多不同颜色的VML元素,你很可能需要优先解决一类元素的问题。

颜色是比较难确定和解释的,但我发现它们是相当宽容的--玩一玩吧。似乎你只需要在元素之间创造足够的对比,以确保color:auto;解析为相同的颜色,并且不改变它是黑暗还是光明模式。

让我们运行一下黑色和白色的应用。

如何在黑暗模式下保持VML内的文本黑色

1.确保你的主体背景是深色的

首先,确保你的主体背景是深色的--#444444或更深。如果你使用的是颜色,那么一个相当暗的阴影应该很好用,但你可能需要做一些实验。

<body style="background-color:#444444;">

你可能更喜欢使用一些条件性的CSS来应用背景颜色,这些条件性的CSS只适用于Outlook 2016+的头部,这取决于你。如果你想这样做,那么在你的代码头部添加这个。

<!--[if gte mso 16]>
    <style>
        body {
            background-color:#444444 !important;
        }
    </style>
<![endif]-->

2.确保你的VML填充是浅色的

如果你希望有黑色的文本,那么有可能它已经是浅色的了。如果你有一个图像填充,那么这对你来说不会有什么区别,因为你不会看到图像背后的颜色。

如果你有一个简单的v:shape ,比如v:ovalv:rect ,那么把fillcolor 设置为#555555或更浅。

<v:rect fillcolor="#555555">

或者,如果你有一个v:fill 元素,那么将颜色设置为#555555或更浅。

<v:fill type="frame" src="image.jpg" color="#555555" />

3.应用自动颜色CSS

比起使用color:auto; ,我发现最好的方法是将mso-color-alt:auto; 添加到你的元素的CSS中,因为这将方便地覆盖你已经在你的元素上设置的任何颜色,而且它只在Outlook中工作,不会干扰任何其他客户端。你可以简单地把它添加到你的文本颜色之后的内联。

<p style="margin:0;color:#000000;mso-color-alt:auto;">Black text</p>

或者,你可以像这样给你的项目添加一个类。

<p class="vml-black" style="margin:0;color:#000000;">Black text</p>

然后把这个CSS添加到你的电子邮件的头部,为了安全起见,限制在新版本的Outlook中。

<!--[if gte mso 16]>
    <style>
        .vml-black {
            mso-color-alt: auto;
        }
    </style>
<![endif]-->

就这样现在发送一个测试,你会看到你的文本在浅色和深色模式下都显示得很好很深。

如何在黑暗模式下保持VML内的文本为白色

1.确保你的主体背景是浅色的

首先,确保你的主体背景是浅色的--#555555或更浅。如果你使用的是颜色,那么一个相当浅的阴影应该很好用,但你可能需要做一些实验。

<body style="background-color:#555555;">

如果你喜欢在有条件的Outlook-only CSS中做这个,你也可以这样做。

<!--[if gte mso 16]>
    <style>
        body {
            background-color:#555555 !important;
        }
    </style>
<![endif]-->

2.确保你的VML填充是深色的

如果你希望得到白色的文本,那么很可能它已经是深色的了。如果你有一个图像填充,那么这对你不会有什么影响,因为你不会看到图像背后的颜色。

如果你只有一个v:shape ,比如v:ovalv:rect ,那么将fillcolor 设置为**#333333或更深**。

<v:rect fillcolor="#333333">

或者,如果你有一个v:fill 元素,那么将颜色设置为#333333或更深。

<v:fill type="frame" src="image.jpg" color="#333333" />

3.应用自动颜色CSS

比起使用color:auto; ,我发现最好的方法是在你的元素的CSS中添加mso-color-alt:auto; ,因为这将方便地覆盖你已经在你的元素上设置的任何颜色,而且它只在Outlook中工作,不会影响任何其他客户端。你可以简单地把它添加到你的文本颜色之后的内联。

<p style="margin:0;color:#ffffff;mso-color-alt:auto;">White text</p>

或者,你可以像这样给你的项目添加一个类。

<p class="vml-white" style="margin:0;color:#ffffff;">White text</p>

然后简单地将这个CSS添加到你的邮件的头部,为了安全起见,限制在新版本的Outlook中。

<!--[if gte mso 16]>
    <style>
        .vml-white {
            mso-color-alt: auto;
        }
    </style>
<![endif]-->

就这样现在发送一个测试,你会看到你的文本在浅色和深色模式下都显示的很好,很白。

3.测 试,测试,测试!

当然,与任何HTML电子邮件的代码解决方案一样,当涉及到在你自己的项目中尝试它时,一定要确保彻底测试。

正如我们在上面看到的,在不止一个测试机构中测试Microsoft 365 Outlook黑暗模式也很重要--如果你使用Litmus,那么你还应该尝试在Email on Acid或Testi上获得一个账户,或者建立你自己的Windows 10测试电脑,以确保你在Microsoft 365 Outlook中看到所有可能的结果。

结论

color:auto; 这个技巧绝对是实验性的,但它对我来说效果非常好。我希望这两个技巧可以为你节省一些时间和压力,很想听听你在自己的邮件中实施这些技巧的实验和结果。