{"id":23659287,"url":"https://github.com/myintervals/emogrifier","last_synced_at":"2025-05-13T16:07:15.706Z","repository":{"id":12255460,"uuid":"14871640","full_name":"MyIntervals/emogrifier","owner":"MyIntervals","description":"Converts CSS styles into inline style attributes in your HTML code.","archived":false,"fork":false,"pushed_at":"2025-05-12T16:59:38.000Z","size":15376,"stargazers_count":928,"open_issues_count":80,"forks_count":154,"subscribers_count":35,"default_branch":"main","last_synced_at":"2025-05-12T18:00:04.137Z","etag":null,"topics":["css","email","hacktoberfest","html","php"],"latest_commit_sha":null,"homepage":"https://www.myintervals.com/emogrifier.php","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MyIntervals.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2013-12-02T18:58:48.000Z","updated_at":"2025-05-06T15:49:09.000Z","dependencies_parsed_at":"2023-12-06T03:21:56.405Z","dependency_job_id":"5f34dfe4-fe6d-4eca-a92e-46b14b99ffa3","html_url":"https://github.com/MyIntervals/emogrifier","commit_stats":{"total_commits":882,"total_committers":48,"mean_commits":18.375,"dds":0.5294784580498866,"last_synced_commit":"878d37d7d9dc5dabdc49452573391cc41c50e300"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MyIntervals%2Femogrifier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MyIntervals%2Femogrifier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MyIntervals%2Femogrifier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MyIntervals%2Femogrifier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MyIntervals","download_url":"https://codeload.github.com/MyIntervals/emogrifier/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253979991,"owners_count":21994041,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css","email","hacktoberfest","html","php"],"created_at":"2024-12-29T02:43:28.524Z","updated_at":"2025-05-13T16:07:15.622Z","avatar_url":"https://github.com/MyIntervals.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Emogrifier\n\n[![Build Status](https://github.com/MyIntervals/emogrifier/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/MyIntervals/emogrifier/actions/)\n[![Latest Stable Version](https://poser.pugx.org/pelago/emogrifier/v/stable.svg)](https://packagist.org/packages/pelago/emogrifier)\n[![Total Downloads](https://poser.pugx.org/pelago/emogrifier/downloads.svg)](https://packagist.org/packages/pelago/emogrifier)\n[![License](https://poser.pugx.org/pelago/emogrifier/license.svg)](https://packagist.org/packages/pelago/emogrifier)\n[![Coverage Status](https://coveralls.io/repos/github/MyIntervals/emogrifier/badge.svg?branch=main)](https://coveralls.io/github/MyIntervals/emogrifier?branch=main)\n\n_n. e•mog•ri•fi•er [\\ē-'mä-grƏ-,fī-Ər\\] - a utility for changing completely the\nnature or appearance of HTML email, esp. in a particularly fantastic or bizarre\nmanner_\n\nEmogrifier converts CSS styles into inline style attributes in your HTML code.\nThis ensures proper display on email and mobile device readers that lack\nstylesheet support.\n\nThis utility was developed as part of [Intervals](http://www.myintervals.com/)\nto deal with the problems posed by certain email clients (namely Outlook 2007\nand GoogleMail) when it comes to the way they handle styling contained in HTML\nemails. As many web developers and designers already know, certain email\nclients are notorious for their lack of CSS support. While attempts are being\nmade to develop common [email standards](http://www.email-standards.org/),\nimplementation is still a ways off.\n\nThe primary problem with uncooperative email clients is that most tend to only\nregard inline CSS, discarding all `\u003cstyle\u003e` elements and links to stylesheets\nin `\u003clink\u003e` elements. Emogrifier solves this problem by converting CSS styles\ninto inline style attributes in your HTML code.\n\n- [How it works](#how-it-works)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Supported CSS selectors](#supported-css-selectors)\n- [Caveats](#caveats)\n- [Contributing](#contributing)\n- [Steps to release a new version](#steps-to-release-a-new-version)\n- [Maintainers](#maintainers)\n\n## How it Works\n\nEmogrifier automagically transmogrifies your HTML by parsing your CSS and\ninserting your CSS definitions into tags within your HTML based on your CSS\nselectors.\n\n## Installation\n\nFor installing emogrifier, either add `pelago/emogrifier` to the `require`\nsection in your project's `composer.json`, or you can use composer as below:\n\n```bash\ncomposer require pelago/emogrifier\n```\n\nSee https://getcomposer.org/ for more information and documentation.\n\n## Usage\n\n### Inlining Css\n\nThe most basic way to use the `CssInliner` class is to create an instance with\nthe original HTML, inline the external CSS, and then get back the resulting\nHTML:\n\n```php\nuse Pelago\\Emogrifier\\CssInliner;\n\n…\n\n$visualHtml = CssInliner::fromHtml($html)-\u003einlineCss($css)-\u003erender();\n```\n\nIf there is no external CSS file and all CSS is located within `\u003cstyle\u003e`\nelements in the HTML, you can omit the `$css` parameter:\n\n```php\n$visualHtml = CssInliner::fromHtml($html)-\u003einlineCss()-\u003erender();\n```\n\nIf you would like to get back only the content of the `\u003cbody\u003e` element instead\nof the complete HTML document, you can use the `renderBodyContent` method\ninstead:\n\n```php\n$bodyContent = $visualHtml = CssInliner::fromHtml($html)-\u003einlineCss()\n  -\u003erenderBodyContent();\n```\n\nIf you would like to modify the inlining process with any of the available\n[options](#options), you will need to call the corresponding methods\nbefore inlining the CSS. The code then would look like this:\n\n```php\n$visualHtml = CssInliner::fromHtml($html)-\u003edisableStyleBlocksParsing()\n  -\u003einlineCss($css)-\u003erender();\n```\n\nThere are also some other HTML-processing classes available\n(all of which are subclasses of `AbstractHtmlProcessor`) which you can use\nto further change the HTML after inlining the CSS.\n(For more details on the classes, please have a look at the sections below.)\n`CssInliner` and all HTML-processing classes can share the same `DOMDocument`\ninstance to work on:\n\n```php\nuse Pelago\\Emogrifier\\CssInliner;\nuse Pelago\\Emogrifier\\HtmlProcessor\\CssToAttributeConverter;\nuse Pelago\\Emogrifier\\HtmlProcessor\\HtmlPruner;\n\n…\n\n$cssInliner = CssInliner::fromHtml($html)-\u003einlineCss($css);\n$domDocument = $cssInliner-\u003egetDomDocument();\nHtmlPruner::fromDomDocument($domDocument)-\u003eremoveElementsWithDisplayNone()\n  -\u003eremoveRedundantClassesAfterCssInlined($cssInliner);\n$finalHtml = CssToAttributeConverter::fromDomDocument($domDocument)\n  -\u003econvertCssToVisualAttributes()-\u003erender();\n```\n\n### Normalizing and cleaning up HTML\n\nThe `HtmlNormalizer` class normalizes the given HTML in the following ways:\n\n- add a document type (HTML5) if missing\n- disentangle incorrectly nested tags\n- add HEAD and BODY elements (if they are missing)\n\nThe class can be used like this:\n\n```php\nuse Pelago\\Emogrifier\\HtmlProcessor\\HtmlNormalizer;\n\n…\n\n$cleanHtml = HtmlNormalizer::fromHtml($rawHtml)-\u003erender();\n```\n\n### Converting CSS styles to visual HTML attributes\n\nThe `CssToAttributeConverter` converts a few style attributes values to visual\nHTML attributes. This allows to get at least a bit of visual styling for email\nclients that do not support CSS well. For example, `style=\"width: 100px\"`\nwill be converted to `width=\"100\"`.\n\nThe class can be used like this:\n\n```php\nuse Pelago\\Emogrifier\\HtmlProcessor\\CssToAttributeConverter;\n\n…\n\n$visualHtml = CssToAttributeConverter::fromHtml($rawHtml)\n  -\u003econvertCssToVisualAttributes()-\u003erender();\n```\n\nYou can also have the `CssToAttributeConverter` work on a `DOMDocument`:\n\n```php\n$visualHtml = CssToAttributeConverter::fromDomDocument($domDocument)\n  -\u003econvertCssToVisualAttributes()-\u003erender();\n```\n\n### Evaluating CSS custom properties (variables)\n\nThe `CssVariableEvaluator` class can be used to apply the values of CSS\nvariables defined in inline style attributes to inline style properties which\nuse them.\n\nFor example, the following CSS defines and uses a custom property:\n\n```css\n:root {\n    --text-color: green;\n}\n\np {\n    color: var(--text-color);\n}\n```\n\nAfter `CssInliner` has inlined that CSS on the (contrived) HTML\n`\u003chtml\u003e\u003cbody\u003e\u003cp\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e`, it will look like this:\n\n```html\n\n\u003chtml style=\"--text-color: green;\"\u003e\n    \u003cbody\u003e\n        \u003cp style=\"color: var(--text-color);\"\u003e\n        \u003cp\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\nThe `CssVariableEvaluator` method `evaluateVariables` will apply the value of\n`--text-color` so that the paragraph `style` attribute becomes `color: green;`.\n\nIt can be used like this:\n\n```php\nuse Pelago\\Emogrifier\\HtmlProcessor\\CssVariableEvaluator;\n\n…\n\n$evaluatedHtml = CssVariableEvaluator::fromHtml($html)\n  -\u003eevaluateVariables()-\u003erender();\n```\n\nYou can also have the ` CssVariableEvaluator ` work on a `DOMDocument`:\n\n```php\n$evaluatedHtml = CssVariableEvaluator::fromDomDocument($domDocument)\n  -\u003eevaluateVariables()-\u003erender();\n```\n\n### Removing redundant content and attributes from the HTML\n\nThe `HtmlPruner` class can reduce the size of the HTML by removing elements with\na `display: none` style declaration, and/or removing classes from `class`\nattributes that are not required.\n\nIt can be used like this:\n\n```php\nuse Pelago\\Emogrifier\\HtmlProcessor\\HtmlPruner;\n\n…\n\n$prunedHtml = HtmlPruner::fromHtml($html)-\u003eremoveElementsWithDisplayNone()\n  -\u003eremoveRedundantClasses($classesToKeep)-\u003erender();\n```\n\nThe `removeRedundantClasses` method accepts an allowlist of names of classes\nthat should be retained. If this is a post-processing step after inlining CSS,\nyou can alternatively use `removeRedundantClassesAfterCssInlined`, passing it\nthe `CssInliner` instance that has inlined the CSS (and having the `HtmlPruner`\nwork on the `DOMDocument`). This will use information from the `CssInliner` to\ndetermine which classes are still required (namely, those used in uninlinable\nrules that have been copied to a `\u003cstyle\u003e` element):\n\n```php\n$prunedHtml = HtmlPruner::fromDomDocument($cssInliner-\u003egetDomDocument())\n  -\u003eremoveElementsWithDisplayNone()\n  -\u003eremoveRedundantClassesAfterCssInlined($cssInliner)-\u003erender();\n```\n\nThe `removeElementsWithDisplayNone` method will not remove any elements which\nhave the class `-emogrifier-keep`. So if, for example, there are elements which\nby default have `display: none` but are revealed by an `@media` rule, or which\nare intended as a preheader, you can add that class to those elements. The\nparagraph in this HTML snippet will not be removed even though it has\n`display: none` (which has presumably been applied by `CssInliner::inlineCss()`\nfrom a CSS rule `.preheader { display: none; }`):\n\n```html\n\u003cp class=\"preheader -emogrifier-keep\" style=\"display: none;\"\u003e\n    Hello World!\n\u003c/p\u003e\n```\n\nThe `removeRedundantClassesAfterCssInlined` (or `removeRedundantClasses`)\nmethod, if invoked after `removeElementsWithDisplayNone`, will remove the\n`-emogrifier-keep` class.\n\n### Options\n\nThere are several options that you can set on the `CssInliner` instance before\ncalling the `inlineCss` method:\n\n* `-\u003edisableStyleBlocksParsing()` - By default, `CssInliner` will grab\n  all `\u003cstyle\u003e` blocks in the HTML and will apply the CSS styles as inline\n  \"style\" attributes to the HTML. The `\u003cstyle\u003e` blocks will then be removed\n  from the HTML. If you want to disable this functionality so that `CssInliner`\n  leaves these `\u003cstyle\u003e` blocks in the HTML and does not parse them, you should\n  use this option. If you use this option, the contents of the `\u003cstyle\u003e` blocks\n  will _not_ be applied as inline styles and any CSS you want `CssInliner` to\n  use must be passed in as described in the [Usage section](#usage) above.\n* `-\u003edisableInlineStyleAttributesParsing()` - By default, `CssInliner`\n  preserves all of the \"style\" attributes on tags in the HTML you pass to it.\n  However if you want to discard all existing inline styles in the HTML before\n  the CSS is applied, you should use this option.\n* `-\u003eaddAllowedMediaType(string $mediaName)` - By default, `CssInliner`\n  will keep only media types `all`, `screen` and `print`. If you want to keep\n  some others, you can use this method to define them.\n* `-\u003eremoveAllowedMediaType(string $mediaName)` - You can use this\n  method to remove media types that Emogrifier keeps.\n* `-\u003eaddExcludedSelector(string $selector)` - Keeps elements from\n  being affected by CSS inlining. Note that only elements matching the supplied\n  selector(s) will be excluded from CSS inlining, not necessarily their\n  descendants. If you wish to exclude an entire subtree, you should provide\n  selector(s) which will match all elements in the subtree, for example by using\n  the universal selector:\n  ```php\n  $cssInliner-\u003eaddExcludedSelector('.message-preview');\n  $cssInliner-\u003eaddExcludedSelector('.message-preview *');\n  ```\n* `-\u003eaddExcludedCssSelector(string $selector)` - Contrary to\n  `addExcludedSelector`, which excludes HTML nodes, this method excludes CSS\n  selectors from being inlined. This is for example useful if you don't want\n  your CSS reset rules to be inlined on each HTML node (e.g.\n  `* { margin: 0; padding: 0; font-size: 100% }`).\n  Note that these selectors must precisely match the selectors you wish to\n  exclude.\n  Meaning that excluding `.example` will not exclude `p .example`.\n  ```php\n  $cssInliner-\u003eaddExcludedCssSelector('*');\n  $cssInliner-\u003eaddExcludedCssSelector('form');\n  ```\n* `-\u003eremoveExcludedCssSelector(string $selector)` - Removes previously added\n  excluded selectors, if any.\n  ```php\n  $cssInliner-\u003eremoveExcludedCssSelector('form');\n  ```\n\n### Migrating from the dropped `Emogrifier` class to the `CssInliner` class\n\n#### Minimal example\n\nOld code using `Emogrifier`:\n\n```php\n$emogrifier = new Emogrifier($html);\n$html = $emogrifier-\u003eemogrify();\n```\n\nNew code using `CssInliner`:\n\n```php\n$html = CssInliner::fromHtml($html)-\u003einlineCss()-\u003erender();\n```\n\nNB: In this example, the old code removes elements with `display: none;`\nwhile the new code does not, as the default behaviors of the old and\nthe new class differ in this regard.\n\n#### More complex example\n\nOld code using `Emogrifier`:\n\n```php\n$emogrifier = new Emogrifier($html, $css);\n$emogrifier-\u003eenableCssToHtmlMapping();\n\n$html = $emogrifier-\u003eemogrify();\n```\n\nNew code using `CssInliner` and family:\n\n```php\n$domDocument = CssInliner::fromHtml($html)-\u003einlineCss($css)-\u003egetDomDocument();\n\nHtmlPruner::fromDomDocument($domDocument)-\u003eremoveElementsWithDisplayNone();\n$html = CssToAttributeConverter::fromDomDocument($domDocument)\n  -\u003econvertCssToVisualAttributes()-\u003erender();\n```\n\n## Supported CSS selectors\n\nEmogrifier currently supports the following\n[CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors):\n\n* [type](https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors)\n* [class](https://developer.mozilla.org/en-US/docs/Web/CSS/Class_selectors)\n* [ID](https://developer.mozilla.org/en-US/docs/Web/CSS/ID_selectors)\n* [universal](https://developer.mozilla.org/en-US/docs/Web/CSS/Universal_selectors)\n* [attribute](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors):\n    * presence\n    * exact value match\n    * value with `~` (one word within a whitespace-separated list of words)\n    * value with `|` (either exact value match or prefix followed by a hyphen)\n    * value with `^` (prefix match)\n    * value with `$` (suffix match)\n    * value with `*` (substring match)\n* [adjacent](https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_selectors)\n* [general sibling](https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_combinator)\n* [child](https://developer.mozilla.org/en-US/docs/Web/CSS/Child_selectors)\n* [descendant](https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_selectors)\n* [pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes):\n    * [empty](https://developer.mozilla.org/en-US/docs/Web/CSS/:empty)\n    * [first-child](https://developer.mozilla.org/en-US/docs/Web/CSS/:first-child)\n    * [first-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:first-of-type)\n      (with a type, e.g. `p:first-of-type` but not `*:first-of-type`)\n    * [last-child](https://developer.mozilla.org/en-US/docs/Web/CSS/:last-child)\n    * [last-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:last-of-type)\n      (with a type)\n    * [not()](https://developer.mozilla.org/en-US/docs/Web/CSS/:not)\n    * [nth-child()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child)\n    * [nth-last-child()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-last-child)\n    * [nth-last-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-last-of-type)\n      (with a type)\n    * [nth-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-of-type)\n      (with a type)\n    * [only-child](https://developer.mozilla.org/en-US/docs/Web/CSS/:only-child)\n    * [only-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:only-of-type)\n      (with a type)\n    * [root](https://developer.mozilla.org/en-US/docs/Web/CSS/:root)\n\nThe following selectors are not implemented yet:\n\n* [case-insensitive attribute value](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors#case-insensitive)\n* static\n  [pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes)\n  not listed above as supported – rules involving them will nonetheless be\n  preserved and copied to a `\u003cstyle\u003e` element in the HTML – including (but not\n  necessarily limited to) the following:\n    * [any-link](https://developer.mozilla.org/en-US/docs/Web/CSS/:any-link)\n    * [first-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:first-of-type)\n      without a type\n    * [last-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:last-of-type)\n      without a type\n    * [nth-last-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-last-of-type)\n      without a type\n    * [nth-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-of-type)\n      without a type\n    * [only-of-type()](https://developer.mozilla.org/en-US/docs/Web/CSS/:only-of-type)\n      without a type\n    * [optional](https://developer.mozilla.org/en-US/docs/Web/CSS/:optional)\n    * [required](https://developer.mozilla.org/en-US/docs/Web/CSS/:required)\n\nRules involving the following selectors cannot be applied as inline styles.\nThey will, however, be preserved and copied to a `\u003cstyle\u003e` element in the HTML:\n\n* dynamic\n  [pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes)\n  (such as `:hover`)\n* [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements)\n  (such as `::after`)\n\n## Caveats\n\n* Emogrifier requires the HTML and the CSS to be UTF-8. Encodings like\n  ISO8859-1 or ISO8859-15 are not supported.\n* Emogrifier preserves all applicable `@media` rules. Media queries can be very\n  useful in responsive email design. See\n  [media query support](https://litmus.com/help/email-clients/media-query-support/).\n  However, in order for them to be effective, you may need to add `!important`\n  to some of the declarations within them so that they will override CSS styles\n  that have been inlined. For example, with the following CSS, the `font-size`\n  declaration in the `@media` rule would not override the font size for `p`\n  elements from the preceding rule after that has been inlined as\n  `\u003cp style=\"font-size: 16px;\"\u003e` in the HTML, without the `!important` directive\n  (even though `!important` would not be necessary if the CSS were not inlined):\n  ```css\n  p {\n    font-size: 16px;\n  }\n  @media (max-width: 640px) {\n    p {\n      font-size: 14px !important;\n    }\n  }\n  ```\n  Any CSS custom properties (variables) defined in `@media` rules cannot be\n  applied to CSS property values that have been inlined and evaluated. However,\n  `@media` rules using custom properties (with `var()`) would still be able to\n  obtain their values (from the inlined definitions or `@media` rules) in email\n  clients that support custom properties.\n* Emogrifier cannot inline CSS rules involving selectors with pseudo-elements\n  (such as `::after`) or dynamic pseudo-classes (such as `:hover`) – it is\n  impossible. However, such rules will be preserved and copied to a `\u003cstyle\u003e`\n  element, as for `@media` rules, with the same caveats applying.\n* Emogrifier will grab existing inline style attributes _and_ will\n  grab `\u003cstyle\u003e` blocks from your HTML, but it will not grab CSS files\n  referenced in `\u003clink\u003e` elements or `@import` rules (though it will leave them\n  intact for email clients that support them).\n* Even with styles inline, certain CSS properties are ignored by certain email\n  clients. For more information, refer to these resources:\n    * [http://www.email-standards.org/](http://www.email-standards.org/)\n    * [https://www.campaignmonitor.com/css/](https://www.campaignmonitor.com/css/)\n    * [http://templates.mailchimp.com/resources/email-client-css-support/](http://templates.mailchimp.com/resources/email-client-css-support/)\n* All CSS attributes that apply to an element will be applied, even if they are\n  redundant. For example, if you define a font attribute _and_ a font-size\n  attribute, both attributes will be applied to that element (in other words,\n  the more specific attribute will not be combined into the more general\n  attribute).\n* There's a good chance you might encounter problems if your HTML is not\n  well-formed and valid (DOMDocument might complain). If you get problems like\n  this, consider running your HTML through\n  [Tidy](http://php.net/manual/en/book.tidy.php) before you pass it to\n  Emogrifier.\n* Emogrifier automatically converts the provided (X)HTML into HTML5, i.e.,\n  self-closing tags will lose their slash. To keep your HTML valid, it is\n  recommended to use HTML5 instead of one of the XHTML variants.\n\n## API and deprecation policy\n\nPlease have a look at our\n[API and deprecation policy](docs/API-and-deprecation-policy.md).\n\n## Contributing\n\nContributions in the form of bug reports, feature requests, or pull requests are\nmore than welcome. :pray: Please have a look at our\n[contribution guidelines](CONTRIBUTING.md) to learn more about how to\ncontribute to Emogrifier.\n\n## Maintainers\n\n* [Oliver Klee](https://github.com/oliverklee)\n* [Zoli Szabó](https://github.com/zoliszabo)\n* [Jake Hotson](https://github.com/JakeQZ)\n* [John Reeve](https://github.com/jjriv)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmyintervals%2Femogrifier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmyintervals%2Femogrifier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmyintervals%2Femogrifier/lists"}