N. e•mog•ri•fi•er [ē-'mä-grƏ-,fī-Ər] – ein Dienstprogramm zum vollständigen Ändern der Art oder des Erscheinungsbilds von HTML-E-Mails, insbesondere. auf besonders fantastische oder skurrile Weise
Emogrifier konvertiert CSS-Stile in Inline-Stilattribute in Ihrem HTML-Code. Dadurch wird die ordnungsgemäße Anzeige auf E-Mail- und Mobilgeräte-Lesegeräten ohne Stylesheet-Unterstützung gewährleistet.
Dieses Dienstprogramm wurde als Teil von Intervals entwickelt, um die Probleme zu lösen, die bestimmte E-Mail-Clients (nämlich Outlook 2007 und GoogleMail) bei der Handhabung von Stilen in HTML-E-Mails verursachen. Wie viele Webentwickler und -designer bereits wissen, sind bestimmte E-Mail-Clients für ihre mangelnde CSS-Unterstützung bekannt. Während Versuche unternommen werden, gemeinsame E-Mail-Standards zu entwickeln, liegt die Umsetzung noch in weiter Ferne.
Das Hauptproblem bei unkooperativen E-Mail-Clients besteht darin, dass die meisten dazu neigen, nur Inline-CSS zu berücksichtigen und alle <style>
-Elemente und Links zu Stylesheets in <link>
-Elementen zu verwerfen. Emogrifier löst dieses Problem, indem es CSS-Stile in Inline-Stilattribute in Ihrem HTML-Code umwandelt.
Emogrifier transmogriert Ihr HTML automatisch, indem es Ihr CSS analysiert und Ihre CSS-Definitionen basierend auf Ihren CSS-Selektoren in Tags in Ihrem HTML einfügt.
Um emogrifier zu installieren, fügen Sie entweder pelago/emogrifier
zum Abschnitt require
in der composer.json
Ihres Projekts hinzu, oder Sie können Composer wie folgt verwenden:
composer require pelago/emogrifier
Weitere Informationen und Dokumentation finden Sie unter https://getcomposer.org/.
Die einfachste Möglichkeit, die CssInliner
-Klasse zu verwenden, besteht darin, eine Instanz mit dem ursprünglichen HTML-Code zu erstellen, das externe CSS zu integrieren und dann den resultierenden HTML-Code zurückzuerhalten:
use Pelago Emogrifier CssInliner ;
…
$ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ( $ css )-> render ();
Wenn keine externe CSS-Datei vorhanden ist und sich das gesamte CSS innerhalb von <style>
-Elementen im HTML befindet, können Sie den $css
Parameter weglassen:
$ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ()-> render ();
Wenn Sie statt des kompletten HTML-Dokuments nur den Inhalt des <body>
-Elements zurückerhalten möchten, können Sie stattdessen die Methode renderBodyContent
verwenden:
$ bodyContent = $ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ()
-> renderBodyContent ();
Wenn Sie den Inlining-Prozess mit einer der verfügbaren Optionen ändern möchten, müssen Sie vor dem Inlining des CSS die entsprechenden Methoden aufrufen. Der Code würde dann so aussehen:
$ visualHtml = CssInliner:: fromHtml ( $ html )-> disableStyleBlocksParsing ()
-> inlineCss ( $ css )-> render ();
Es stehen auch einige andere HTML-Verarbeitungsklassen zur Verfügung (die alle Unterklassen von AbstractHtmlProcessor
sind), mit denen Sie den HTML-Code nach dem Inlining des CSS weiter ändern können. (Weitere Einzelheiten zu den Klassen finden Sie in den folgenden Abschnitten.) CssInliner
und alle HTML-verarbeitenden Klassen können dieselbe DOMDocument
Instanz nutzen, um daran zu arbeiten:
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 ();
Die HtmlNormalizer
-Klasse normalisiert den angegebenen HTML-Code auf folgende Weise:
Die Klasse kann wie folgt verwendet werden:
use Pelago Emogrifier HtmlProcessor HtmlNormalizer ;
…
$ cleanHtml = HtmlNormalizer:: fromHtml ( $ rawHtml )-> render ();
Der CssToAttributeConverter
konvertiert einige Stilattributwerte in visuelle HTML-Attribute. Dies ermöglicht es, E-Mail-Clients, die CSS nicht gut unterstützen, zumindest ein wenig visuelles Styling zu erhalten. Beispielsweise wird style="width: 100px"
in width="100"
konvertiert.
Die Klasse kann wie folgt verwendet werden:
use Pelago Emogrifier HtmlProcessor CssToAttributeConverter ;
…
$ visualHtml = CssToAttributeConverter:: fromHtml ( $ rawHtml )
-> convertCssToVisualAttributes ()-> render ();
Sie können den CssToAttributeConverter
auch an einem DOMDocument
arbeiten lassen:
$ visualHtml = CssToAttributeConverter:: fromDomDocument ( $ domDocument )
-> convertCssToVisualAttributes ()-> render ();
Die CssVariableEvaluator
-Klasse kann verwendet werden, um die Werte von CSS-Variablen, die in Inline-Stilattributen definiert sind, auf Inline-Stileigenschaften anzuwenden, die sie verwenden.
Das folgende CSS definiert und verwendet beispielsweise eine benutzerdefinierte Eigenschaft:
: root {
--text-color : green;
}
p {
color : var ( --text-color );
}
Nachdem CssInliner
dieses CSS in den (erfundenen) HTML-Code <html><body><p></p></body></html>
eingefügt hat, sieht es folgendermaßen aus:
< html style =" --text-color: green; " >
< body >
< p style =" color: var(--text-color); " >
< p >
</ body >
</ html >
Die Methode evaluateVariables
CssVariableEvaluator
wendet den Wert von --text-color
an, sodass das style
zu color: green;
.
Es kann wie folgt verwendet werden:
use Pelago Emogrifier HtmlProcessor CssVariableEvaluator ;
…
$ evaluatedHtml = CssVariableEvaluator:: fromHtml ( $ html )
-> evaluateVariables ()-> render ();
Sie können den CssVariableEvaluator
auch an einem DOMDocument
arbeiten lassen:
$ evaluatedHtml = CssVariableEvaluator:: fromDomDocument ( $ domDocument )
-> evaluateVariables ()-> render ();
Die HtmlPruner
-Klasse kann die Größe des HTML reduzieren, indem sie Elemente mit einer display: none
Stildeklaration entfernt und/oder Klassen aus class
entfernt, die nicht erforderlich sind.
Es kann wie folgt verwendet werden:
use Pelago Emogrifier HtmlProcessor HtmlPruner ;
…
$ prunedHtml = HtmlPruner:: fromHtml ( $ html )-> removeElementsWithDisplayNone ()
-> removeRedundantClasses ( $ classesToKeep )-> render ();
Die Methode removeRedundantClasses
akzeptiert eine Zulassungsliste mit Namen von Klassen, die beibehalten werden sollen. Wenn dies ein Nachbearbeitungsschritt nach dem Inlining von CSS ist, können Sie alternativ removeRedundantClassesAfterCssInlined
verwenden und ihm die CssInliner
Instanz übergeben, die das CSS eingebunden hat (und den HtmlPruner
auf dem DOMDocument
arbeiten lassen). Dabei werden Informationen aus dem CssInliner
verwendet, um zu bestimmen, welche Klassen noch erforderlich sind (nämlich diejenigen, die in nicht inlinierbaren Regeln verwendet werden, die in ein <style>
-Element kopiert wurden):
$ prunedHtml = HtmlPruner:: fromDomDocument ( $ cssInliner -> getDomDocument ())
-> removeElementsWithDisplayNone ()
-> removeRedundantClassesAfterCssInlined ( $ cssInliner )-> render ();
Die Methode removeElementsWithDisplayNone
entfernt keine Elemente mit der Klasse -emogrifier-keep
. Wenn es also beispielsweise Elemente gibt, die standardmäßig display: none
haben, aber durch eine @media
-Regel angezeigt werden, oder die als Preheader gedacht sind, können Sie diese Klasse zu diesen Elementen hinzufügen. Der Absatz in diesem HTML-Snippet wird nicht entfernt, obwohl er display: none
hat (was vermutlich von CssInliner::inlineCss()
aus einer CSS-Regel .preheader { display: none; }
angewendet wurde):
< p class =" preheader -emogrifier-keep " style =" display: none; " >
Hello World!
</ p >
Die Methode removeRedundantClassesAfterCssInlined
(oder removeRedundantClasses
“) entfernt, wenn sie nach removeElementsWithDisplayNone
aufgerufen wird, die Klasse -emogrifier-keep
.
Es gibt mehrere Optionen, die Sie für die CssInliner
Instanz festlegen können, bevor Sie die inlineCss
-Methode aufrufen:
->disableStyleBlocksParsing()
– Standardmäßig erfasst CssInliner
alle <style>
-Blöcke im HTML und wendet die CSS-Stile als Inline-„Stil“-Attribute auf den HTML-Code an. Die <style>
-Blöcke werden dann aus dem HTML entfernt. Wenn Sie diese Funktionalität deaktivieren möchten, sodass CssInliner
diese <style>
-Blöcke im HTML belässt und nicht analysiert, sollten Sie diese Option verwenden. Wenn Sie diese Option verwenden, werden die Inhalte der <style>
-Blöcke nicht als Inline-Stile angewendet und alle CSS, die CssInliner
verwenden soll, müssen wie im Abschnitt „Verwendung“ oben beschrieben übergeben werden.->disableInlineStyleAttributesParsing()
– Standardmäßig behält CssInliner
alle „Stil“-Attribute für Tags im HTML bei, die Sie ihm übergeben. Wenn Sie jedoch alle vorhandenen Inline-Stile im HTML verwerfen möchten, bevor das CSS angewendet wird, sollten Sie diese Option verwenden.->addAllowedMediaType(string $mediaName)
– Standardmäßig behält CssInliner
nur die Medientypen all
, screen
und print
bei. Wenn Sie einige andere behalten möchten, können Sie diese Methode verwenden, um sie zu definieren.->removeAllowedMediaType(string $mediaName)
– Sie können diese Methode verwenden, um Medientypen zu entfernen, die Emogrifier behält.->addExcludedSelector(string $selector)
– Verhindert, dass Elemente durch CSS-Inlining beeinträchtigt werden. Beachten Sie, dass nur Elemente, die mit den angegebenen Selektoren übereinstimmen, vom CSS-Inlining ausgeschlossen werden, nicht unbedingt ihre Nachkommen. Wenn Sie einen gesamten Unterbaum ausschließen möchten, sollten Sie einen oder mehrere Selektoren bereitstellen, die alle Elemente im Unterbaum abgleichen, beispielsweise mithilfe des universellen Selektors: $ cssInliner -> addExcludedSelector ( ' .message-preview ' );
$ cssInliner -> addExcludedSelector ( ' .message-preview * ' );
->addExcludedCssSelector(string $selector)
– Im Gegensatz zu addExcludedSelector
, das HTML-Knoten ausschließt, schließt diese Methode CSS-Selektoren von der Inline-Einbindung aus. Dies ist beispielsweise nützlich, wenn Sie nicht möchten, dass Ihre CSS-Reset-Regeln in jedem HTML-Knoten eingebunden werden (z. B. * { margin: 0; padding: 0; font-size: 100% }
). Beachten Sie, dass diese Selektoren genau mit den Selektoren übereinstimmen müssen, die Sie ausschließen möchten. Das bedeutet, dass durch das Ausschließen von .example
p .example
nicht ausgeschlossen wird. $ cssInliner -> addExcludedCssSelector ( ' * ' );
$ cssInliner -> addExcludedCssSelector ( ' form ' );
->removeExcludedCssSelector(string $selector)
– Entfernt zuvor hinzugefügte ausgeschlossene Selektoren, falls vorhanden. $ cssInliner -> removeExcludedCssSelector ( ' form ' );
Emogrifier
-Klasse zur CssInliner
-Klasse Alter Code mit Emogrifier
:
$ emogrifier = new Emogrifier ( $ html );
$ html = $ emogrifier -> emogrify ();
Neuer Code mit CssInliner
:
$ html = CssInliner:: fromHtml ( $ html )-> inlineCss ()-> render ();
Hinweis: In diesem Beispiel entfernt der alte Code Elemente mit display: none;
Im neuen Code ist dies jedoch nicht der Fall, da sich die Standardverhaltensweisen der alten und der neuen Klasse in dieser Hinsicht unterscheiden.
Alter Code mit Emogrifier
:
$ emogrifier = new Emogrifier ( $ html , $ css );
$ emogrifier -> enableCssToHtmlMapping ();
$ html = $ emogrifier -> emogrify ();
Neuer Code mit CssInliner
und Familie:
$ domDocument = CssInliner:: fromHtml ( $ html )-> inlineCss ( $ css )-> getDomDocument ();
HtmlPruner:: fromDomDocument ( $ domDocument )-> removeElementsWithDisplayNone ();
$ html = CssToAttributeConverter:: fromDomDocument ( $ domDocument )
-> convertCssToVisualAttributes ()-> render ();
Emogrifier unterstützt derzeit die folgenden CSS-Selektoren:
~
(ein Wort in einer durch Leerzeichen getrennten Liste von Wörtern)|
(entweder exakte Wertübereinstimmung oder Präfix gefolgt von einem Bindestrich)^
(Präfixübereinstimmung)$
(Suffix-Übereinstimmung)*
(Teilzeichenfolgenübereinstimmung)p:first-of-type
, aber nicht *:first-of-type
)Die folgenden Selektoren sind noch nicht implementiert:
<style>
-Element im HTML kopiert – einschließlich (aber nicht unbedingt beschränkt auf) Folgendes: Regeln mit den folgenden Selektoren können nicht als Inline-Stile angewendet werden. Sie bleiben jedoch erhalten und werden in ein <style>
-Element im HTML kopiert:
:hover
)::after
) @media
-Regeln bei. Medienabfragen können beim responsiven E-Mail-Design sehr nützlich sein. Siehe Unterstützung für Medienabfragen. Damit sie jedoch wirksam sind, müssen Sie möglicherweise einigen der darin enthaltenen Deklarationen !important
hinzufügen, damit sie inline eingebundene CSS-Stile überschreiben. Mit dem folgenden CSS würde beispielsweise die font-size
in der @media
-Regel die Schriftgröße für p
Elemente aus der vorhergehenden Regel nicht überschreiben, nachdem diese als <p style="font-size: 16px;">
eingebunden wurde im HTML, ohne die !important
-Direktive (obwohl !important
nicht notwendig wäre, wenn das CSS nicht inline wäre): p {
font-size : 16 px ;
}
@media ( max-width : 640 px ) {
p {
font-size : 14 px !important ;
}
}
@media
-Regeln definierten benutzerdefinierten CSS-Eigenschaften (Variablen) können nicht auf CSS-Eigenschaftswerte angewendet werden, die eingebunden und ausgewertet wurden. Allerdings könnten @media
-Regeln, die benutzerdefinierte Eigenschaften verwenden (mit var()
), ihre Werte (von den inline-Definitionen oder @media
-Regeln) weiterhin in E-Mail-Clients abrufen, die benutzerdefinierte Eigenschaften unterstützen.::after
) oder dynamischen Pseudoklassen (z. B. :hover
) beinhalten – das ist unmöglich. Solche Regeln bleiben jedoch erhalten und werden wie bei @media
-Regeln in ein <style>
-Element kopiert, wobei dieselben Einschränkungen gelten.<style>
-Blöcke aus Ihrem HTML-Code zu, aber nicht auf CSS-Dateien, auf die in <link>
-Elementen oder @import
-Regeln verwiesen wird (obwohl sie für E-Mail-Clients, die sie unterstützen, intakt bleiben).Bitte werfen Sie einen Blick auf unsere API- und Einstellungsrichtlinien.
Beiträge in Form von Fehlerberichten, Funktionsanfragen oder Pull-Anfragen sind mehr als willkommen. Bitte werfen Sie einen Blick auf unsere Spendenrichtlinien, um mehr darüber zu erfahren, wie Sie bei Emogrifier spenden können.
branch-alias
Eintrag so, dass er auf die Veröffentlichung nach der bevorstehenden Veröffentlichung verweist.