n. e•mog•ri•fi•er [ē-'mä-grƏ-,fī-Ər] - HTML 電子メールの性質や外観を完全に変更するためのユーティリティ。特に幻想的または奇妙な方法で
Emogrifier は、CSS スタイルを HTML コードのインライン スタイル属性に変換します。これにより、スタイルシートがサポートされていない電子メールやモバイル デバイス リーダーでも適切に表示されるようになります。
このユーティリティは、HTML メールに含まれるスタイルの処理方法に関して特定の電子メール クライアント (つまり、Outlook 2007 および GoogleMail) によって引き起こされる問題に対処するために、Intervals の一部として開発されました。多くの Web 開発者やデザイナーがすでに知っているように、特定の電子メール クライアントは CSS サポートがないことで有名です。共通の電子メール標準を開発する試みが行われていますが、実装はまだ先のことです。
非協力的な電子メール クライアントの主な問題は、ほとんどがインライン CSS のみを考慮し、すべての<style>
要素と<link>
要素内のスタイルシートへのリンクを破棄する傾向があることです。 Emogrifier は、CSS スタイルを HTML コード内のインライン スタイル属性に変換することで、この問題を解決します。
Emogrifier は、CSS を解析し、CSS セレクターに基づいて HTML 内のタグに CSS 定義を挿入することにより、HTML を魔法のように自動的に変換します。
emogrifier をインストールするには、プロジェクトのcomposer.json
のrequire
セクションにpelago/emogrifier
追加するか、以下のように 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 ();
完全な HTML ドキュメントではなく、 <body>
要素のコンテンツのみを取得したい場合は、代わりに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
その CSS を (人為的な) HTML <html><body><p></p></body></html>
にインライン化すると、次のようになります。
< html style =" --text-color: green; " >
< body >
< p style =" color: var(--text-color); " >
< p >
</ body >
</ html >
CssVariableEvaluator
メソッドのevaluateVariables
段落style
属性がcolor: green;
になるように--text-color
の値を適用します。 。
次のように使用できます。
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
(おそらく CSS ルール.preheader { display: none; }
} からCssInliner::inlineCss()
によって適用されています) があっても削除されません。
< p class =" preheader -emogrifier-keep " style =" display: none; " >
Hello World!
</ p >
removeRedundantClassesAfterCssInlined
(またはremoveRedundantClasses
) メソッドは、 removeElementsWithDisplayNone
の後に呼び出された場合、 -emogrifier-keep
クラスを削除します。
inlineCss
メソッドを呼び出す前に、 CssInliner
インスタンスに設定できるオプションがいくつかあります。
->disableStyleBlocksParsing()
- デフォルトでは、 CssInliner
HTML 内のすべての<style>
ブロックを取得し、CSS スタイルをインラインの「style」属性として 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 セレクターをサポートしています。
~
を含む値 (空白で区切られた単語のリスト内の 1 つの単語)|
を含む値(値が完全に一致するか、接頭辞の後にハイフンが続くかのいずれか)^
を含む値 (前方一致)$
を含む値 (サフィックス一致)*
を含む値 (部分文字列一致)p:first-of-type
ではなく、 *:first-of-type
ではありません)次のセレクターはまだ実装されていません。
<style>
要素にコピーされます。これには、次のものが含まれます (ただし、必ずしもこれらに限定されるわけではありません)。次のセレクターを含むルールは、インライン スタイルとして適用できません。ただし、これらは保持され、HTML の<style>
要素にコピーされます。
:hover
など)::after
など) @media
ルールを保持します。メディア クエリは、レスポンシブな電子メールのデザインに非常に役立ちます。メディア クエリのサポートを参照してください。ただし、これらを有効にするには、インライン化された CSS スタイルをオーバーライドできるように、宣言内の一部の宣言に!important
追加する必要がある場合があります。たとえば、次の CSS では、 @media
ルールのfont-size
宣言は、<p style="font-size: 16px;"> としてインライン化された後、前のルールの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 ルールをインライン化できません。これは不可能です。ただし、そのようなルールは@media
ルールと同様に保存され、 <style>
要素にコピーされますが、同じ注意事項が適用されます。<style>
ブロックを取得しますが、 <link>
要素または@import
ルールで参照されている CSS ファイルは取得しません (ただし、CSS ファイルをサポートする電子メール クライアントにはそのまま残ります)。API と非推奨ポリシーをご覧ください。
バグレポート、機能リクエスト、プルリクエストなどの形での貢献は大歓迎です。 Emogrifier への貢献方法の詳細については、貢献ガイドラインをご覧ください。
branch-alias
エントリを更新します。