名詞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
條目以指向即將發布的版本之後的版本。