premailer
Turns CSS blocks into inline style attributes for HTML email compatibility
Repository Health
Technical Analysis
premailer converts HTML documents with <style> blocks or linked stylesheets into email-client-safe markup by inlining the resolved CSS as style attributes on each element. Since most email clients strip or ignore <style> tags and external stylesheets, this inlining step is a near-mandatory part of any transactional or marketing email pipeline that authors templates with normal CSS.
Under the hood it parses the page and CSS with lxml.html/cssutils, resolves selector specificity, and rewrites the DOM tree so each element carries its computed inline styles. It can optionally fetch external stylesheets by URL (allow_network), strip now-redundant <style>/<link> tags, and is usable as both a Python API and a python -m premailer CLI.
What You Get
- A
transform()shortcut function andPremailerclass for converting HTML with CSS into inline-styled HTML - Support for both
<style>blocks and externally linked stylesheets, with optional network fetching viaallow_network - CSS cascade/specificity resolution so inlined styles match what a browser would actually apply
- Optional removal of now-redundant
<style>/<link>tags and classes after inlining - A
python -m premailercommand-line interface for one-off conversions outside of application code
Common Use Cases
- Inlining CSS for transactional or marketing HTML emails before sending via an ESP or SMTP relay
- Converting a maintainable CSS-based email template into the flat inline-style HTML that email clients render correctly
- Batch-processing a set of HTML email templates as part of a build/deploy pipeline
- Stripping and inlining styles for HTML that needs to render consistently across environments that ignore
<style>tags
Under The Hood
Architecture: The core logic lives in premailer/premailer.py (732 lines), which parses HTML via lxml.html, extracts and resolves CSS rules (including specificity ordering) via cssutils, and walks the DOM tree merging computed styles into each element’s style attribute using logic in merge_style.py; cache.py memoizes parsed external stylesheets to avoid refetching them across repeated calls.
Tech Stack: Pure Python built on lxml for HTML/DOM manipulation and cssutils for CSS parsing, with __main__.py exposing a CLI entry point alongside the importable API.
Code Quality: A substantial test suite (test_premailer.py, test_merge_style.py, test_cache.py, test_utils.py) exercises inlining against real-world HTML fixtures (test-apple-newsletter.html, test-unicode.html, and named regression fixtures like test-issue78.html), with CI configured via Travis per the README badges.
API Design: The one-line transform(html) shortcut covers the common case, while the Premailer class exposes options (allow_network, remove_classes, strip_important) for more controlled pipelines — a low-friction API, though the network-fetching default for external stylesheets is a behavior teams should explicitly opt out of if unwanted.