
名词e•mog•ri•fi•er [ē-'mä-grƏ-,fī-Ər] - 用于完全更改 HTML 电子邮件(尤其是电子邮件)的性质或外观的实用程序。以一种特别奇妙或奇怪的方式
Emogrifier 将 CSS 样式转换为 HTML 代码中的内联样式属性。这可确保在缺乏样式表支持的电子邮件和移动设备阅读器上正确显示。
该实用程序是作为 Intervals 的一部分开发的,旨在解决某些电子邮件客户端(即 Outlook 2007 和 GoogleMail)在处理 HTML 电子邮件中包含的样式的方式时出现的问题。正如许多 Web 开发人员和设计师已经知道的那样,某些电子邮件客户端因缺乏 CSS 支持而臭名昭著。尽管人们正在尝试制定通用电子邮件标准,但实施仍有很长的路要走。
不合作的电子邮件客户端的主要问题是大多数倾向于只考虑内联 CSS,丢弃所有<style>元素以及指向<link>元素中样式表的链接。 Emogrifier 通过将 CSS 样式转换为 HTML 代码中的内联样式属性来解决此问题。
Emogrifier 通过解析您的 CSS 并根据您的 CSS 选择器将 CSS 定义插入到 HTML 内的标签中,自动改变您的 HTML。
要安装 emogrifier,请将pelago/emogrifier添加到项目的composer.json中的require部分,或者您可以使用composer,如下所示:
composer require pelago/emogrifier请参阅 https://getcomposer.org/ 了解更多信息和文档。
使用CssInliner类的最基本方法是使用原始 HTML 创建一个实例,内联外部 CSS,然后返回生成的 HTML:
use Pelago Emogrifier CssInliner ;
…
$ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ( $ css )-> render ();如果没有外部 CSS 文件并且所有 CSS 都位于 HTML 中的<style>元素内,则可以省略$css参数:
$ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ()-> render ();如果您只想返回<body>元素的内容而不是完整的 HTML 文档,您可以使用renderBodyContent方法:
$ bodyContent = $ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ()
-> renderBodyContent ();如果您想使用任何可用选项修改内联过程,则需要在内联 CSS 之前调用相应的方法。代码将如下所示:
$ visualHtml = CssInliner:: fromHtml ( $ html )-> disableStyleBlocksParsing ()
-> inlineCss ( $ css )-> render ();还有一些其他可用的 HTML 处理类(所有这些类都是AbstractHtmlProcessor的子类),您可以在内联 CSS 后使用它们进一步更改 HTML。 (有关这些类的更多详细信息,请查看以下部分。) CssInliner和所有 HTML 处理类可以共享相同的DOMDocument实例来处理:
use Pelago Emogrifier CssInliner ;
use Pelago Emogrifier HtmlProcessor CssToAttributeConverter ;
use Pelago Emogrifier HtmlProcessor HtmlPruner ;
…
$ cssInliner = CssInliner:: fromHtml ( $ html )-> inlineCss ( $ css );
$ domDocument = $ cssInliner -> getDomDocument ();
HtmlPruner:: fromDomDocument ( $ domDocument )-> removeElementsWithDisplayNone ()
-> removeRedundantClassesAfterCssInlined ( $ cssInliner );
$ finalHtml = CssToAttributeConverter:: fromDomDocument ( $ domDocument )
-> convertCssToVisualAttributes ()-> render (); HtmlNormalizer类通过以下方式标准化给定的 HTML:
该类可以这样使用:
use Pelago Emogrifier HtmlProcessor HtmlNormalizer ;
…
$ cleanHtml = HtmlNormalizer:: fromHtml ( $ rawHtml )-> render ();CssToAttributeConverter将一些样式属性值转换为可视 HTML 属性。这允许为不太支持 CSS 的电子邮件客户端至少获得一些视觉样式。例如, style="width: 100px"将转换为width="100" 。
该类可以这样使用:
use Pelago Emogrifier HtmlProcessor CssToAttributeConverter ;
…
$ visualHtml = CssToAttributeConverter:: fromHtml ( $ rawHtml )
-> convertCssToVisualAttributes ()-> render ();您还可以让CssToAttributeConverter在DOMDocument上工作:
$ visualHtml = CssToAttributeConverter:: fromDomDocument ( $ domDocument )
-> convertCssToVisualAttributes ()-> render (); CssVariableEvaluator类可用于将内联样式属性中定义的 CSS 变量的值应用到使用它们的内联样式属性。
例如,以下 CSS 定义并使用自定义属性:
: root {
--text-color : green;
}
p {
color : var ( --text-color );
} CssInliner在(设计的)HTML <html><body><p></p></body></html>上内联该 CSS 后,它将如下所示:
< html style =" --text-color: green; " >
< body >
< p style =" color: var(--text-color); " >
< p >
</ body >
</ html > CssVariableEvaluator方法evaluateVariables将应用--text-color的值,使段落style属性变为color: green; 。
它可以这样使用:
use Pelago Emogrifier HtmlProcessor CssVariableEvaluator ;
…
$ evaluatedHtml = CssVariableEvaluator:: fromHtml ( $ html )
-> evaluateVariables ()-> render ();您还可以让CssVariableEvaluator在DOMDocument上工作:
$ evaluatedHtml = CssVariableEvaluator:: fromDomDocument ( $ domDocument )
-> evaluateVariables ()-> render ();HtmlPruner类可以通过删除具有display: none样式声明的元素和/或从不需要的class属性中删除类来减小 HTML 的大小。
它可以这样使用:
use Pelago Emogrifier HtmlProcessor HtmlPruner ;
…
$ prunedHtml = HtmlPruner:: fromHtml ( $ html )-> removeElementsWithDisplayNone ()
-> removeRedundantClasses ( $ classesToKeep )-> render (); removeRedundantClasses方法接受应保留的类名称白名单。如果这是内联 CSS 后的后处理步骤,您也可以使用removeRedundantClassesAfterCssInlined ,将其传递给已内联 CSS CssInliner实例(并让HtmlPruner在DOMDocument上工作)。这将使用来自CssInliner的信息来确定仍然需要哪些类(即,在已复制到<style>元素的不可内联规则中使用的类):
$ prunedHtml = HtmlPruner:: fromDomDocument ( $ cssInliner -> getDomDocument ())
-> removeElementsWithDisplayNone ()
-> removeRedundantClassesAfterCssInlined ( $ cssInliner )-> render (); removeElementsWithDisplayNone方法不会删除任何具有类-emogrifier-keep元素。因此,例如,如果某些元素默认具有display: none但通过@media规则显示,或者打算用作前置头,则可以将该类添加到这些元素中。此 HTML 代码段中的段落不会被删除,即使它具有display: none (这可能是由CssInliner::inlineCss()从 CSS 规则.preheader { display: none; }应用的):
< p class =" preheader -emogrifier-keep " style =" display: none; " >
Hello World!
</ p >如果在removeElementsWithDisplayNone之后调用removeRedundantClassesAfterCssInlined (或removeRedundantClasses )方法,将删除-emogrifier-keep类。
在调用inlineCss方法之前,您可以在CssInliner实例上设置几个选项:
->disableStyleBlocksParsing() - 默认情况下, CssInliner将抓取 HTML 中的所有<style>块,并将 CSS 样式作为内联“样式”属性应用到 HTML。然后, <style>块将从 HTML 中删除。如果您想禁用此功能,以便CssInliner将这些<style>块保留在 HTML 中并且不解析它们,您应该使用此选项。如果您使用此选项, <style>块的内容将不会应用为内联样式,并且您希望CssInliner使用的任何 CSS 都必须按照上面的“用法”部分中的描述传入。->disableInlineStyleAttributesParsing() - 默认情况下, CssInliner会保留传递给它的 HTML 中标记上的所有“样式”属性。但是,如果您想在应用 CSS 之前放弃 HTML 中所有现有的内联样式,则应该使用此选项。->addAllowedMediaType(string $mediaName) - 默认情况下, CssInliner将仅保留媒体类型all 、 screen和print 。如果你想保留一些其他的,你可以使用这个方法来定义它们。->removeAllowedMediaType(string $mediaName) - 您可以使用此方法删除 Emogrifier 保留的媒体类型。->addExcludedSelector(string $selector) - 防止元素受到 CSS 内联的影响。请注意,只有与所提供的选择器匹配的元素才会被排除在 CSS 内联之外,而不一定是它们的后代。如果您希望排除整个子树,则应提供将匹配子树中所有元素的选择器,例如通过使用通用选择器: $ cssInliner -> addExcludedSelector ( ' .message-preview ' );
$ cssInliner -> addExcludedSelector ( ' .message-preview * ' );->addExcludedCssSelector(string $selector) - 与排除 HTML 节点的addExcludedSelector相反,此方法排除内联 CSS 选择器。例如,如果您不希望 CSS 重置规则内联在每个 HTML 节点上(例如* { margin: 0; padding: 0; font-size: 100% } ),这非常有用。请注意,这些选择器必须与您要排除的选择器精确匹配。这意味着排除.example不会排除p .example 。 $ cssInliner -> addExcludedCssSelector ( ' * ' );
$ cssInliner -> addExcludedCssSelector ( ' form ' );->removeExcludedCssSelector(string $selector) - 删除之前添加的排除选择器(如果有)。 $ cssInliner -> removeExcludedCssSelector ( ' form ' );Emogrifier类迁移到CssInliner类使用Emogrifier的旧代码:
$ emogrifier = new Emogrifier ( $ html );
$ html = $ emogrifier -> emogrify ();使用CssInliner的新代码:
$ html = CssInliner:: fromHtml ( $ html )-> inlineCss ()-> render ();注意:在此示例中,旧代码删除带有display: none;而新代码则不然,因为新旧类的默认行为在这方面有所不同。
使用Emogrifier的旧代码:
$ emogrifier = new Emogrifier ( $ html , $ css );
$ emogrifier -> enableCssToHtmlMapping ();
$ html = $ emogrifier -> emogrify ();使用CssInliner和系列的新代码:
$ domDocument = CssInliner:: fromHtml ( $ html )-> inlineCss ( $ css )-> getDomDocument ();
HtmlPruner:: fromDomDocument ( $ domDocument )-> removeElementsWithDisplayNone ();
$ html = CssToAttributeConverter:: fromDomDocument ( $ domDocument )
-> convertCssToVisualAttributes ()-> render ();Emogrifier 目前支持以下 CSS 选择器:
~值(空格分隔的单词列表中的一个单词)| (精确值匹配或前缀后跟连字符)^的值(前缀匹配)$的值(后缀匹配)*的值(子字符串匹配)p:first-of-type但不是*:first-of-type )以下选择器尚未实现:
<style>元素 - 包括(但不一定限于)以下内容:涉及以下选择器的规则不能应用为内联样式。但是,它们将被保留并复制到 HTML 中的<style>元素中:
:hover )::after ) @media规则。媒体查询在响应式电子邮件设计中非常有用。请参阅媒体查询支持。但是,为了使它们有效,您可能需要向其中的某些声明添加!important ,以便它们覆盖已内联的 CSS 样式。例如,对于以下 CSS, @media规则中的font-size声明不会覆盖前一规则中p元素的字体大小,之后内联为<p style="font-size: 16px;">在 HTML 中,没有!important指令(尽管如果 CSS 没有内联,就不需要!important ): p {
font-size : 16 px ;
}
@media ( max-width : 640 px ) {
p {
font-size : 14 px !important ;
}
}@media规则中定义的任何 CSS 自定义属性(变量)都不能应用于已内联和计算的 CSS 属性值。但是,使用自定义属性(使用var() )的@media规则仍然能够在支持自定义属性的电子邮件客户端中获取其值(从内联定义或@media规则)。::after )或动态伪类(例如:hover )的选择器的 CSS 规则——这是不可能的。但是,此类规则将被保留并复制到<style>元素,就像@media规则一样,并应用相同的注意事项。<style>块,但它不会抓取<link>元素或@import规则中引用的 CSS 文件(尽管它会让支持它们的电子邮件客户端保持完整)。请查看我们的 API 和弃用政策。
我们非常欢迎以错误报告、功能请求或拉取请求的形式做出贡献。请查看我们的贡献指南,了解有关如何为 Emogrifier 做出贡献的更多信息。
branch-alias条目以指向即将发布的版本之后的版本。