Skip to content
Derek Paul edited this page Jun 29, 2015 · 5 revisions

CSS Inliner

Turns CSS Style blocks into inlined style

This user manual will help you understand, install, and run the CSS Inliner.

The CSS Inliner is an Open Source project expanding on the premailer made originally by Peterbe, found here: https://github.com/peterbe/premailer and branching from Sendwithus’ version, found here: https://github.com/sendwithus/premailer

What is a CSS Inliner?

The purpose of the CSS Inliner is to read a user’s Cascading Style Sheets (CSS) and reformat it so it is compatible with email clients.

When you send HyperText Markup Language (HTML) emails, all the styling for the email have to be created a certain way. This called an inlined style.

Why does it exist?

Simply because email is stuck in the past. We can use HTML when creating email templates, but many email clients strip out elements that are necessary for the common use of CSS, which breaks the styling of the email content.

Example:

Normally, you would code this way:

<html>
<style type="text/css">
h1 { border:1px solid black }
p { color:red;}
</style>
<h1 style="font-weight:bolder">Peter</h1>
<p>Hej</p>
</html>

You want this:

<html>
<h1 style="font-weight:bolder; border:1px solid black">Peter</h1>
<p style="color:red">Hej</p>
</html>

The CSS Inliner will achieve this for you. It reads the HTML page, extracts the style attributes and matches them to the corresponding element in the body of the page. The Team Space Monkey’s version of the CSS Inliner will now extract metadata from the page as well. This will be used to extract key attributes for support purposes.

Getting Started

If you haven’t done so, download the CSS Inliner:

$ pip install git+https://github.com/BlokeOne/premailer-1.git 

Next, the basic way to use the CSS Inliner is to run it through your python command line:

>>> from premailer import transform
>>> print transform("""
...         <html>
...         <style type="text/css">
...         h1 { border:1px solid black }
...         p { color:red;}
...         p::first-letter { float:left; }
...         </style>
...         <h1 style="font-weight:bolder">Peter</h1>
...         <p>Hej</p>
...         </html>
... """)
<html>
<head></head>
<body>
<h1 style="font-weight:bolder; border:1px solid black">Peter</h1>
        <p style="color:red">Hej</p>
        </body>
</html>

For more advanced options, check out the code of the Premailer class and all its options in its constructor.

You can also use premailer from the command line by using his main module.

$ python -m premailer -h
usage: python -m premailer [options]

optional arguments:
-h, --help            show this help message and exit
-f [INFILE], --file [INFILE]
                       Specifies the input file. The default is stdin.
-o [OUTFILE], --output [OUTFILE]
                      Specifies the output file. The default is stdout.
--base-url BASE_URL
--remove-internal-links PRESERVE_INTERNAL_LINKS
                      Remove links that start with a '#' like anchors.
--exclude-pseudoclasses
                      Pseudo classes like p:last-child', p:first-child, etc
--preserve-style-tags
                      Do not delete <style></style> tags from the html
                      document.
--remove-star-selectors
                      All wildcard selectors like '* {color: black}' will be
                      removed.
--remove-classes      Remove all class attributes from all elements
--metadata                                                       -
                      Extract Metadata from the input HTML.
--strip-important     Remove '!important' for all css declarations.
--disable-basic-attributes Disable provided basic attributes (comma separated)
--disable-validation  Disable CSSParser validation of attributes and values
--disable-exceptions
                      Disable exception raising using the CSSParser validation from cssutils as well as HTML errors using lxml. Does not disable empty rule exception. 

A basic example:

$ python -m premailer --base-url=http://google.com/ -f newsletter.html
<html>
<head><style>.heading { color:red; }</style></head>
<body><h1 class="heading" style="color:red"><a href="http://google.com/">Title</a></h1></body>
</html>

Unit tests can be run from the command line using the following command. test_premailer.py must be run from the command line using:

>>> nosetests premailer/test_premailer.py   

If you are using Python Version 3+, use:

>>> python2.7 -m nose premailer/test_premailer.py

Unknown Rules and Properties

@keyframes raises a warning as is considered unknown since it is not in cssutils’ collection of rules.
Various properties such as -ms-interpolation-mode are also considered unknown for the same reason and raise warnings.

HTML attributes created additionally

Certain HTML attributes are also created on the HTML if the CSS contains any ones that are easily translated into HTML attributes. For example, if you have this CSS: td { background-color:#eee; } then this is transformed into style="background-color:#eee" AND as an HTML attribute bgcolor="#eee". Having these extra attributes basically as a "backup" for really bad email clients that can't even take the style attributes. A lot of professional HTML newsletters such as Amazon's use this. You can disable some attributes in disable_basic_attributes

Gathering Metadata

To enable metadata, you must add metadata=True for example:

def transform(html, base_url=None):
    return Premailer(html, metadata=True).transform()

When this is enabled, transform will return both its usual transformed code and metadata.
We suggest using prettyprint for readability.

import pprint 

p = Premailer(html)
pp = pprint.PrettyPrinter(indent=2)
transformed_html, meta = transform(html)
print transformed_html
print pp.pprint(meta)

Error Reporting

Error-reporting is enabled by default, but can be disabled:

def transform(html, base_url=None):
    return Premailer(html, disable_exceptions=True).transform()