n. e•mog•ri•fi•er [ē-'mä-grƏ-,fī-Ər] - un utilitaire pour changer complètement la nature ou l'apparence du courrier électronique HTML, en particulier. d'une manière particulièrement fantastique ou bizarre
Emogrifier convertit les styles CSS en attributs de style en ligne dans votre code HTML. Cela garantit un affichage correct sur les lecteurs de courrier électronique et d’appareils mobiles qui ne prennent pas en charge les feuilles de style.
Cet utilitaire a été développé dans le cadre d'Intervals pour résoudre les problèmes posés par certains clients de messagerie (notamment Outlook 2007 et GoogleMail) dans la façon dont ils gèrent le style contenu dans les emails HTML. Comme de nombreux développeurs et concepteurs Web le savent déjà, certains clients de messagerie sont connus pour leur manque de prise en charge CSS. Bien que des tentatives soient faites pour développer des normes communes de courrier électronique, leur mise en œuvre est encore loin d’être effective.
Le principal problème avec les clients de messagerie peu coopératifs est que la plupart ont tendance à ne considérer que le CSS en ligne, en supprimant tous les éléments <style>
et les liens vers les feuilles de style dans les éléments <link>
. Emogrifier résout ce problème en convertissant les styles CSS en attributs de style en ligne dans votre code HTML.
Emogrifier transmogrifie automatiquement votre HTML en analysant votre CSS et en insérant vos définitions CSS dans des balises de votre HTML en fonction de vos sélecteurs CSS.
Pour installer emogrifier, ajoutez pelago/emogrifier
à la section require
dans le composer.json
de votre projet, ou vous pouvez utiliser composer comme ci-dessous :
composer require pelago/emogrifier
Voir https://getcomposer.org/ pour plus d'informations et de documentation.
La manière la plus simple d'utiliser la classe CssInliner
consiste à créer une instance avec le HTML d'origine, à intégrer le CSS externe, puis à récupérer le HTML résultant :
use Pelago Emogrifier CssInliner ;
…
$ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ( $ css )-> render ();
S'il n'y a pas de fichier CSS externe et que tous les CSS se trouvent dans les éléments <style>
du HTML, vous pouvez omettre le paramètre $css
:
$ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ()-> render ();
Si vous souhaitez récupérer uniquement le contenu de l'élément <body>
au lieu du document HTML complet, vous pouvez utiliser la méthode renderBodyContent
à la place :
$ bodyContent = $ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ()
-> renderBodyContent ();
Si vous souhaitez modifier le processus d'inline avec l'une des options disponibles, vous devrez appeler les méthodes correspondantes avant d'inline le CSS. Le code ressemblerait alors à ceci :
$ visualHtml = CssInliner:: fromHtml ( $ html )-> disableStyleBlocksParsing ()
-> inlineCss ( $ css )-> render ();
Il existe également d'autres classes de traitement HTML disponibles (qui sont toutes des sous-classes de AbstractHtmlProcessor
) que vous pouvez utiliser pour modifier davantage le HTML après avoir intégré le CSS. (Pour plus de détails sur les classes, veuillez consulter les sections ci-dessous.) CssInliner
et toutes les classes de traitement HTML peuvent partager la même instance DOMDocument
sur laquelle travailler :
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 ();
La classe HtmlNormalizer
normalise le code HTML donné des manières suivantes :
La classe peut être utilisée comme ceci :
use Pelago Emogrifier HtmlProcessor HtmlNormalizer ;
…
$ cleanHtml = HtmlNormalizer:: fromHtml ( $ rawHtml )-> render ();
Le CssToAttributeConverter
convertit quelques valeurs d'attributs de style en attributs HTML visuels. Cela permet d'obtenir au moins un peu de style visuel pour les clients de messagerie qui ne supportent pas bien CSS. Par exemple, style="width: 100px"
sera converti en width="100"
.
La classe peut être utilisée comme ceci :
use Pelago Emogrifier HtmlProcessor CssToAttributeConverter ;
…
$ visualHtml = CssToAttributeConverter:: fromHtml ( $ rawHtml )
-> convertCssToVisualAttributes ()-> render ();
Vous pouvez également faire fonctionner le CssToAttributeConverter
sur un DOMDocument
:
$ visualHtml = CssToAttributeConverter:: fromDomDocument ( $ domDocument )
-> convertCssToVisualAttributes ()-> render ();
La classe CssVariableEvaluator
peut être utilisée pour appliquer les valeurs des variables CSS définies dans les attributs de style en ligne aux propriétés de style en ligne qui les utilisent.
Par exemple, le CSS suivant définit et utilise une propriété personnalisée :
: root {
--text-color : green;
}
p {
color : var ( --text-color );
}
Une fois que CssInliner
a intégré ce CSS sur le HTML (artificiel) <html><body><p></p></body></html>
, cela ressemblera à ceci :
< html style =" --text-color: green; " >
< body >
< p style =" color: var(--text-color); " >
< p >
</ body >
</ html >
La méthode CssVariableEvaluator
evaluateVariables
appliquera la valeur de --text-color
afin que l'attribut style
de paragraphe devienne color: green;
.
Il peut être utilisé comme ceci :
use Pelago Emogrifier HtmlProcessor CssVariableEvaluator ;
…
$ evaluatedHtml = CssVariableEvaluator:: fromHtml ( $ html )
-> evaluateVariables ()-> render ();
Vous pouvez également faire fonctionner le CssVariableEvaluator
sur un DOMDocument
:
$ evaluatedHtml = CssVariableEvaluator:: fromDomDocument ( $ domDocument )
-> evaluateVariables ()-> render ();
La classe HtmlPruner
peut réduire la taille du code HTML en supprimant les éléments avec une déclaration de style display: none
et/ou en supprimant les classes des attributs class
qui ne sont pas requis.
Il peut être utilisé comme ceci :
use Pelago Emogrifier HtmlProcessor HtmlPruner ;
…
$ prunedHtml = HtmlPruner:: fromHtml ( $ html )-> removeElementsWithDisplayNone ()
-> removeRedundantClasses ( $ classesToKeep )-> render ();
La méthode removeRedundantClasses
accepte une liste verte de noms de classes qui doivent être conservées. S'il s'agit d'une étape de post-traitement après l'incorporation du CSS, vous pouvez également utiliser removeRedundantClassesAfterCssInlined
, en lui transmettant l'instance CssInliner
qui a intégré le CSS (et en faisant fonctionner HtmlPruner
sur le DOMDocument
). Cela utilisera les informations de CssInliner
pour déterminer quelles classes sont encore requises (à savoir celles utilisées dans les règles non inlinables qui ont été copiées dans un élément <style>
) :
$ prunedHtml = HtmlPruner:: fromDomDocument ( $ cssInliner -> getDomDocument ())
-> removeElementsWithDisplayNone ()
-> removeRedundantClassesAfterCssInlined ( $ cssInliner )-> render ();
La méthode removeElementsWithDisplayNone
ne supprimera aucun élément ayant la classe -emogrifier-keep
. Ainsi, si, par exemple, il y a des éléments qui ont par défaut display: none
mais qui sont révélés par une règle @media
, ou qui sont destinés à servir de pré-en-tête, vous pouvez ajouter cette classe à ces éléments. Le paragraphe de cet extrait HTML ne sera pas supprimé même s'il contient display: none
(qui a probablement été appliqué par CssInliner::inlineCss()
à partir d'une règle CSS .preheader { display: none; }
) :
< p class =" preheader -emogrifier-keep " style =" display: none; " >
Hello World!
</ p >
La méthode removeRedundantClassesAfterCssInlined
(ou removeRedundantClasses
), si elle est invoquée après removeElementsWithDisplayNone
, supprimera la classe -emogrifier-keep
.
Il existe plusieurs options que vous pouvez définir sur l'instance CssInliner
avant d'appeler la méthode inlineCss
:
->disableStyleBlocksParsing()
- Par défaut, CssInliner
récupérera tous les blocs <style>
dans le HTML et appliquera les styles CSS en tant qu'attributs "style" en ligne au HTML. Les blocs <style>
seront alors supprimés du HTML. Si vous souhaitez désactiver cette fonctionnalité afin que CssInliner
laisse ces blocs <style>
dans le HTML et ne les analyse pas, vous devez utiliser cette option. Si vous utilisez cette option, le contenu des blocs <style>
ne sera pas appliqué en tant que styles en ligne et tout CSS que vous souhaitez que CssInliner
utilise doit être transmis comme décrit dans la section Utilisation ci-dessus.->disableInlineStyleAttributesParsing()
- Par défaut, CssInliner
conserve tous les attributs « style » sur les balises du code HTML que vous lui transmettez. Cependant, si vous souhaitez supprimer tous les styles en ligne existants dans le HTML avant que le CSS ne soit appliqué, vous devez utiliser cette option.->addAllowedMediaType(string $mediaName)
- Par défaut, CssInliner
conservera uniquement les types de médias all
, screen
et print
. Si vous souhaitez en conserver d’autres, vous pouvez utiliser cette méthode pour les définir.->removeAllowedMediaType(string $mediaName)
- Vous pouvez utiliser cette méthode pour supprimer les types de médias conservés par Emogrifier.->addExcludedSelector(string $selector)
- Empêche les éléments d'être affectés par l'inlining CSS. Notez que seuls les éléments correspondant au(x) sélecteur(s) fourni(s) seront exclus de l'inline CSS, pas nécessairement leurs descendants. Si vous souhaitez exclure un sous-arbre entier, vous devez fournir un ou plusieurs sélecteurs qui correspondront à tous les éléments du sous-arbre, par exemple en utilisant le sélecteur universel : $ cssInliner -> addExcludedSelector ( ' .message-preview ' );
$ cssInliner -> addExcludedSelector ( ' .message-preview * ' );
->addExcludedCssSelector(string $selector)
- Contrairement à addExcludedSelector
, qui exclut les nœuds HTML, cette méthode exclut les sélecteurs CSS d'être intégrés. Ceci est par exemple utile si vous ne souhaitez pas que vos règles de réinitialisation CSS soient intégrées sur chaque nœud HTML (par exemple * { margin: 0; padding: 0; font-size: 100% }
). Notez que ces sélecteurs doivent correspondre précisément aux sélecteurs que vous souhaitez exclure. Cela signifie que l'exclusion de .example
n'exclura pas p .example
. $ cssInliner -> addExcludedCssSelector ( ' * ' );
$ cssInliner -> addExcludedCssSelector ( ' form ' );
->removeExcludedCssSelector(string $selector)
- Supprime les sélecteurs exclus précédemment ajoutés, le cas échéant. $ cssInliner -> removeExcludedCssSelector ( ' form ' );
Emogrifier
abandonnée vers la classe CssInliner
Ancien code utilisant Emogrifier
:
$ emogrifier = new Emogrifier ( $ html );
$ html = $ emogrifier -> emogrify ();
Nouveau code utilisant CssInliner
:
$ html = CssInliner:: fromHtml ( $ html )-> inlineCss ()-> render ();
NB : Dans cet exemple, l'ancien code supprime les éléments avec display: none;
alors que le nouveau code ne le fait pas, car les comportements par défaut de l'ancienne et de la nouvelle classe diffèrent à cet égard.
Ancien code utilisant Emogrifier
:
$ emogrifier = new Emogrifier ( $ html , $ css );
$ emogrifier -> enableCssToHtmlMapping ();
$ html = $ emogrifier -> emogrify ();
Nouveau code utilisant CssInliner
et sa famille :
$ domDocument = CssInliner:: fromHtml ( $ html )-> inlineCss ( $ css )-> getDomDocument ();
HtmlPruner:: fromDomDocument ( $ domDocument )-> removeElementsWithDisplayNone ();
$ html = CssToAttributeConverter:: fromDomDocument ( $ domDocument )
-> convertCssToVisualAttributes ()-> render ();
Emogrifier prend actuellement en charge les sélecteurs CSS suivants :
~
(un mot dans une liste de mots séparés par des espaces)|
(soit une correspondance de valeur exacte, soit un préfixe suivi d'un trait d'union)^
(correspondance du préfixe)$
(correspondance du suffixe)*
(correspondance de sous-chaîne)p:first-of-type
mais pas *:first-of-type
)Les sélecteurs suivants ne sont pas encore implémentés :
<style>
dans le HTML – y compris (mais sans nécessairement s'y limiter) les éléments suivants : Les règles impliquant les sélecteurs suivants ne peuvent pas être appliquées en tant que styles en ligne. Ils seront cependant conservés et copiés dans un élément <style>
du HTML :
:hover
)::after
) @media
applicables. Les requêtes multimédias peuvent être très utiles dans la conception d’e-mails réactifs. Voir prise en charge des requêtes multimédias. Cependant, pour qu'ils soient efficaces, vous devrez peut-être ajouter !important
à certaines des déclarations qu'ils contiennent afin qu'elles remplacent les styles CSS qui ont été intégrés. Par exemple, avec le CSS suivant, la déclaration font-size
dans la règle @media
ne remplacerait pas la taille de police des éléments p
de la règle précédente après qu'elle ait été insérée comme <p style="font-size: 16px;">
dans le HTML, sans la directive !important
(même si !important
ne serait pas nécessaire si le CSS n'était pas intégré) : p {
font-size : 16 px ;
}
@media ( max-width : 640 px ) {
p {
font-size : 14 px !important ;
}
}
@media
ne peuvent pas être appliquées aux valeurs de propriété CSS qui ont été intégrées et évaluées. Cependant, les règles @media
utilisant des propriétés personnalisées (avec var()
) pourront toujours obtenir leurs valeurs (à partir des définitions intégrées ou des règles @media
) dans les clients de messagerie prenant en charge les propriétés personnalisées.::after
) ou des pseudo-classes dynamiques (telles que :hover
) – c'est impossible. Cependant, ces règles seront conservées et copiées dans un élément <style>
, comme pour les règles @media
, avec les mêmes mises en garde s'appliquant.<style>
de votre code HTML, mais il ne récupérera pas les fichiers CSS référencés dans les éléments <link>
ou les règles @import
(bien qu'il les laissera intacts pour les clients de messagerie qui les prennent en charge).Veuillez consulter notre API et notre politique de dépréciation.
Les contributions sous forme de rapports de bogues, de demandes de fonctionnalités ou de demandes d'extraction sont plus que bienvenues. Veuillez consulter nos directives de contribution pour en savoir plus sur la façon de contribuer à Emogrifier.
branch-alias
pour qu’elle pointe vers la version postérieure à la version à venir.