Fast CSS inlining written in Rust
Project description
css_inline
Blazing-fast CSS inlining for Python implemented with Mozilla's Servo project components.
Features:
- Removing
style
tags after inlining; - Resolving external stylesheets (including local files);
- Control if
style
tags should be processed; - Out-of-document CSS to inline;
- Inlining multiple documents in parallel (via Rust-level threads)
The project supports CSS Syntax Level 3.
Installation
To install css_inline
via pip
run the following command:
pip install css_inline
Pre-compiled wheels for most popular platforms are provided. If your platform is not in the support table below, you will need a Rust compiler to build this package from source. The minimum supported Rust version is 1.54.
Usage
To inline CSS in a HTML document:
import css_inline
HTML = """<html>
<head>
<title>Test</title>
<style>h1 { color:blue; }</style>
</head>
<body>
<h1>Big Text</h1>
</body>
</html>"""
inlined = css_inline.inline(HTML)
# HTML becomes this:
#
# <html>
# <head>
# <title>Test</title>
# <style>h1 { color:blue; }</style>
# </head>
# <body>
# <h1 style="color:blue;">Big Text</h1>
# </body>
# </html>
If you want to inline many HTML documents, you can utilize inline_many
that processes the input in parallel.
import css_inline
css_inline.inline_many(["<...>", "<...>"])
inline_many
will use Rust-level threads; thus, you can expect it's running faster than css_inline.inline
via Python's multiprocessing
or threading
modules.
For customization options use the CSSInliner
class:
import css_inline
inliner = css_inline.CSSInliner(remove_style_tags=True)
inliner.inline("...")
If you'd like to skip CSS inlining for an HTML tag, add data-css-inline="ignore"
attribute to it:
<head>
<title>Test</title>
<style>h1 { color:blue; }</style>
</head>
<body>
<!-- The tag below won't receive additional styles -->
<h1 data-css-inline="ignore">Big Text</h1>
</body>
</html>
This attribute also allows you to skip link
and style
tags:
<head>
<title>Test</title>
<!-- Styles below are ignored -->
<style data-css-inline="ignore">h1 { color:blue; }</style>
</head>
<body>
<h1>Big Text</h1>
</body>
</html>
Performance
Due to the usage of efficient tooling from Mozilla's Servo project (html5ever
, rust-cssparser
and others) this
library has excellent performance characteristics. In comparison with other Python projects, it is usually >10x faster than the nearest alternative.
For inlining CSS in the html document from the Usage
section above there is the following breakdown in the benchmarks:
css_inline 0.8.2
- 22.42 uspremailer 3.10.0
- 332.02 us (x14.81)toronado 0.1.0
- 1.59 ms (x71.17)inlinestyler 0.2.5
- 2.35 ms (x105.07)pynliner 0.8.0
- 2.79 ms (x124.80)
Realistic email 1:
css_inline 0.8.2
- 487.75 uspremailer 3.10.0
- 3.92 ms (x8.05)toronado 0.1.0
- 52.09 ms (x106.81)inlinestyler 0.2.5
- 81.17 ms (x166.43)pynliner 0.8.0
- 128.81 ms (x264.1)
Realistic email 2:
css_inline 0.8.2
- 386.64 uspremailer 3.10.0
- 4.82 ms (x12.47)toronado 0.1.0
-Error: Pseudo-elements are not supported
inlinestyler 0.2.5
- 40.80 ms (x105.54)pynliner 0.8.0
-Error: No match was found
You can take a look at the benchmarks' code at benches/bench.py
file.
The results above were measured with stable rustc 1.64.0
, Python 3.10.4
, Linux x86_64
on i8700K, and 32GB RAM.
Comparison with other libraries
Besides performance, css-inline
differs from other Python libraries for CSS inlining.
- Generally supports more CSS features than other libraries (for example,
toronado
andpynliner
do not support pseudo-elements); - It has fewer configuration options and not as flexible as
premailer
; - Works on fewer platforms than LXML-based libraries (
premailer
,inlinestyler
,toronado
, and optionallypynliner
); - Does not have debug logs yet;
- Supports only HTML 5.
Python support
css_inline
supports CPython 3.7, 3.8, 3.9, 3.10, 3.11 and PyPy 3.7, 3.8, 3.9.
Extra materials
If you want to know how this library was created & how it works internally, you could take a look at these articles:
License
The code in this project is licensed under MIT license.
By contributing to css_inline
, you agree that your contributions
will be licensed under its MIT license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for css_inline-0.8.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fee26c517e89486b373bdcb5b003e0bba2792936d7a3ef509996b4796d13a94c |
|
MD5 | 9543d1d80022bf26161fe87609cc292f |
|
BLAKE2b-256 | e8b13c980fefd7cf28510f9f8b25c58d2e1227e841463e650d4a016124df8fea |
Hashes for css_inline-0.8.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a2bc3f4e891af90386d03e8d3f8af5f970772a300c2b199ab4841a09ab0b6377 |
|
MD5 | 15159bb8b658a6073952f0a868823dad |
|
BLAKE2b-256 | 35a4378f1e0a750c3a7453a2a83ffcb9fefc708862ca5005a9ee04c07c533e33 |
Hashes for css_inline-0.8.5-pp39-pypy39_pp73-macosx_10_7_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | cd2191930b20fa43415c94e365bc7e38017f71b47ed797c2f31eb4a1a5c11fbc |
|
MD5 | 376d500b42f0e2950903d9f7b19c5638 |
|
BLAKE2b-256 | fffbe890ba195031d8564b5dde958e3cf6bfabae8b795c1b7ba8a408c4a1ad51 |
Hashes for css_inline-0.8.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f4818955f9ca2ab013c7100480cf2e64239bc386c36a47e471ce5056776cf0d3 |
|
MD5 | d9aabd931501fe07dad1c3ec189db203 |
|
BLAKE2b-256 | 8073f789456e084732dde928a08dc7404d47525121ed902b652f57b00c2641ce |
Hashes for css_inline-0.8.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1eb36d37b8aeaec4d534933bb206759222e567cc1fe655e3d548665231fb79db |
|
MD5 | 70988266d71b9ca5e7c41c91a82d330a |
|
BLAKE2b-256 | 70881c88bc3ec29add7fa458ac7b472b0345205e697a567f31daad0b7b69d42d |
Hashes for css_inline-0.8.5-pp38-pypy38_pp73-macosx_10_7_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ab0101e6aae4ea4ff6be5b4e2e3ec4549b227781d142ee0ed0277d4b8b8b0985 |
|
MD5 | 5b663c222711ecf57f9a1fc3bb205af0 |
|
BLAKE2b-256 | 0220bd2c302d9c73474e01d9f122d54a2cf30c6a1677232597e7ae77c0ffdc7b |
Hashes for css_inline-0.8.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 10ce512ca23fc45bddf9367ef1e1cb1d5ff6414cf3ac6f2ec5b8d6c3e6aff8a4 |
|
MD5 | 20c1f1fe91901dd77f4aa3c712cf8d52 |
|
BLAKE2b-256 | 79f8db048aa0a1d7aeba8df663b2efb10fd8e8aca4d9df650a7002f561fa1b90 |
Hashes for css_inline-0.8.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 52f0d6a2a82200e0b504282a41be0608b09b15d8efd5788ec7ad471d51d75402 |
|
MD5 | c1dafe70d2587b9643a74b3d62c1e4b9 |
|
BLAKE2b-256 | 3229c6d8ed25e34b56a676dbd04765ea55e9ead44388a666f82a757a284c5a79 |
Hashes for css_inline-0.8.5-pp37-pypy37_pp73-macosx_10_7_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9821672e94cf5df9e6021be859fe561a6fadefc5aa5cf00f39896a4447b17c37 |
|
MD5 | 126c908bab4d844697101acdbc5c9063 |
|
BLAKE2b-256 | f3baddc350a95b39686939099b198d7ed4ce380ff502d50373a7b7b086abdbd1 |
Hashes for css_inline-0.8.5-cp37-abi3-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 674d74bb03cded8598dd563c35ad2698d4680b7aa93c5de940b95e6ebb239526 |
|
MD5 | 17d4228a57f491be7ce1101609d05667 |
|
BLAKE2b-256 | 98a568f796a63cd2b295799a70ddf6c0ce6220dc85534d8c3965c0d4ad1ebb05 |
Hashes for css_inline-0.8.5-cp37-abi3-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d9bced3b76901153a1d936ab319abee1cde002bf39dd2f617cbac3bc9eeef6d4 |
|
MD5 | b4e422a2ab4b37592f89ebe352c93590 |
|
BLAKE2b-256 | 306fd86a40371a78801016785732462e080c8522f5c794ea3ca18753efc0c1ac |
Hashes for css_inline-0.8.5-cp37-abi3-musllinux_1_2_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7ef1cca785576d748a80065ab324c344d65c35634327954e65697ff457c4d3a9 |
|
MD5 | 5f9d33069fd25a0fd9be73fd1fbbf271 |
|
BLAKE2b-256 | a198a7651c4a4dc38afa443e42b6cdaed3561a029e05717892c89f58c9229870 |
Hashes for css_inline-0.8.5-cp37-abi3-musllinux_1_2_armv7l.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b2f5d67cb3819fe39edc0d788bde8bf88b37ed530639ec52df8b6d6bf3b060e7 |
|
MD5 | 608c205c3cfd4def4f09e1d5e1f01e6a |
|
BLAKE2b-256 | f4196d703917f6b0412b8104c9702b117cace40c910c881ec2bc5a0ae3efa617 |
Hashes for css_inline-0.8.5-cp37-abi3-musllinux_1_2_aarch64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f5c182aff736f4eab731e123ffc5ff7c60d09c18754fcb1525caea38bb67881a |
|
MD5 | beb8a75a6be6628284617d7799c0929c |
|
BLAKE2b-256 | 95c8011563cb6bd9f8fb4aa2d90c132297ba5de54b34a2f6f00c04abe6c8af00 |
Hashes for css_inline-0.8.5-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6b55a9992eb131f93dcd5a0fc9eb246a66e108e7eaa9e69d1aab9d5f8e42ba8f |
|
MD5 | 6dcd6c2fd099516035bd0b63d1cf23ed |
|
BLAKE2b-256 | 23bc93dfd6e69340b44aa9f5efe185e0d72ed60e7fb78ee7d3be2b46a9978920 |
Hashes for css_inline-0.8.5-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 57e5186246b74737e98e0cb35be4f90c39abe30aa6fe94155788c71a00e32029 |
|
MD5 | 4f6e3ecc8cb9d01246fa9421a149249d |
|
BLAKE2b-256 | 47b1afffe58da670a2bfa0632de8156a21970345b05a070e82d0fc1eac2ed5f0 |
Hashes for css_inline-0.8.5-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 364ea7de58bf874b8819b85c211e1e9a44141d7b09c47edf65290f98b35e4cb3 |
|
MD5 | a480f8f0c5ad44f9c8d863ee5f563d01 |
|
BLAKE2b-256 | 35575772bbe171ed54c5d87bf714f3be8f1ce79f97efafe9793a816c65aeca38 |
Hashes for css_inline-0.8.5-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 244abed844eec2b542219e64e74a361f96813082af734e21b028538691ed2d70 |
|
MD5 | 3531bdb6d0efd49edbad19957eec8504 |
|
BLAKE2b-256 | 5cc8b44577c9b0e5547f71aad61f4c60f249eb695c6ca413ccbf933c43512207 |
Hashes for css_inline-0.8.5-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f040dfad748a14a4b2f495d9927a2f4ffcba1459aa17d1676ca1a1cbd024e624 |
|
MD5 | ee55e038b42a8519072971d4759ffd06 |
|
BLAKE2b-256 | 0ad833cd58e85f324a7e5c3fb9d8e63b7c8886f9c2d6fba5ef9cbb195f20b5b8 |
Hashes for css_inline-0.8.5-cp37-abi3-macosx_10_7_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7ebdadb6ff03265f798ce5343ac8af73477c9aea78b69f0dbb524982c8422a90 |
|
MD5 | ea345405a343973abe44d6b375722059 |
|
BLAKE2b-256 | fce9b9d1f2f3a2259b70cba64bfcd3860b428641106eabc2db57106cf0fd96c0 |