N. e•mog•ri•fi•er [ē-'mä-grτ-,fī-ŏr] - HTML 이메일의 특성이나 모양을 완전히 변경하는 유틸리티입니다. 특히 환상적이거나 기괴한 방식으로
Emogrifier는 CSS 스타일을 HTML 코드의 인라인 스타일 속성으로 변환합니다. 이렇게 하면 스타일시트 지원이 부족한 이메일 및 모바일 장치 리더에 올바르게 표시됩니다.
이 유틸리티는 HTML 이메일에 포함된 스타일을 처리하는 방식과 관련하여 특정 이메일 클라이언트(예: Outlook 2007 및 GoogleMail)에서 발생하는 문제를 처리하기 위해 Intervals의 일부로 개발되었습니다. 많은 웹 개발자와 디자이너가 이미 알고 있듯이 특정 이메일 클라이언트는 CSS 지원이 부족한 것으로 유명합니다. 공통 이메일 표준을 개발하려는 시도가 이루어지고 있지만 구현은 아직 멀었습니다.
비협조적인 이메일 클라이언트의 주요 문제는 대부분 인라인 CSS만 고려하고 모든 <style>
요소와 <link>
요소의 스타일시트 링크를 삭제하는 경향이 있다는 것입니다. Emogrifier는 CSS 스타일을 HTML 코드의 인라인 스타일 속성으로 변환하여 이 문제를 해결합니다.
Emogrifier는 CSS를 구문 분석하고 CSS 선택기를 기반으로 HTML 내의 태그에 CSS 정의를 삽입하여 HTML을 자동으로 변환합니다.
emogrifier를 설치하려면 프로젝트의 composer.json
에 있는 require
섹션에 pelago/emogrifier
추가하거나 아래와 같이 작곡가를 사용할 수 있습니다.
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 ();
CSS를 인라인 처리한 후 HTML을 추가로 변경하는 데 사용할 수 있는 다른 HTML 처리 클래스(모두 AbstractHtmlProcessor
의 하위 클래스)도 있습니다. (클래스에 대한 자세한 내용은 아래 섹션을 참조하세요.) 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 ();
DOMDocument
에서 CssToAttributeConverter
작동하도록 할 수도 있습니다.
$ 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
단락 style
속성이 color: green이 되도록 --text-color
값을 적용합니다 color: green;
.
다음과 같이 사용할 수 있습니다.
use Pelago Emogrifier HtmlProcessor CssVariableEvaluator ;
…
$ evaluatedHtml = CssVariableEvaluator:: fromHtml ( $ html )
-> evaluateVariables ()-> render ();
DOMDocument
에서 CssVariableEvaluator
작동하도록 할 수도 있습니다.
$ 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 스타일을 HTML에 인라인 "스타일" 속성으로 적용합니다. 그러면 <style>
블록이 HTML에서 제거됩니다. CssInliner
HTML에 이러한 <style>
블록을 남겨두고 구문 분석하지 않도록 이 기능을 비활성화하려면 이 옵션을 사용해야 합니다. 이 옵션을 사용하는 경우 <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
규칙을 유지합니다. 미디어 쿼리는 반응형 이메일 디자인에 매우 유용할 수 있습니다. 미디어 쿼리 지원을 참조하세요. 그러나 이러한 기능이 효과적이려면 인라인된 CSS 스타일을 재정의할 수 있도록 일부 선언에 !important
추가해야 할 수도 있습니다. 예를 들어, 다음 CSS를 사용하면 @media
규칙의 font-size
선언은 <p style="font-size: 16px;">
로 인라인된 이후 이전 규칙의 p
요소에 대한 글꼴 크기를 재정의하지 않습니다. 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 파일은 가져오지 않습니다(단, 이를 지원하는 이메일 클라이언트에서는 그대로 유지합니다).API 및 지원 중단 정책을 살펴보시기 바랍니다.
버그 보고서, 기능 요청, 풀 요청 형태의 기여는 매우 환영합니다. Emogrifier에 기여하는 방법에 대해 자세히 알아보려면 기여 지침을 살펴보시기 바랍니다.
branch-alias
항목을 업데이트합니다.