Skip to main content

High-performance library for inlining CSS into HTML 'style' attributes

Project description

css_inline

build status pypi versions license codecov.io gitter

css_inline is a high-performance library for inlining CSS into HTML 'style' attributes.

This library is designed for scenarios such as preparing HTML emails or embedding HTML into third-party web pages.

For instance, the library transforms HTML like this:

<html>
    <head>
        <style>h1 { color:blue; }</style>
    </head>
    <body>
        <h1>Big Text</h1>
    </body>
</html>

into:

<html>
    <head></head>
    <body>
        <h1 style="color:blue;">Big Text</h1>
    </body>
</html>
  • Uses reliable components from Mozilla's Servo project
  • 10-300x faster than alternatives
  • Inlines CSS from style and link tags
  • Removes style and link tags
  • Resolves external stylesheets (including local files)
  • Can process multiple documents in parallel
  • Works on Linux, Windows, and macOS
  • Supports HTML5 & CSS3

Installation

Install with pip:

pip install css_inline

Pre-compiled wheels are available for most popular platforms. If not available for your platform, a Rust compiler will be needed to build this package from source. Rust version 1.60 or higher is required.

Usage

import css_inline

HTML = """<html>
<head>
    <style>h1 { color:blue; }</style>
</head>
<body>
    <h1>Big Text</h1>
</body>
</html>"""

inlined = css_inline.inline(HTML)
# HTML becomes this:
#
# <html>
# <head>
#    <style>h1 { color:blue; }</style>
# </head>
# <body>
#     <h1 style="color:blue;">Big Text</h1>
# </body>
# </html>

When there is a need to inline multiple HTML documents simultaneously, css_inline offers the inline_many function. This feature allows for concurrent processing of several inputs, significantly improving performance when dealing with a large number of documents.

import css_inline

css_inline.inline_many(["<...>", "<...>"])

Under the hood, inline_many, spawns threads at the Rust layer to handle the parallel processing of inputs. This results in faster execution times compared to employing parallel processing techniques at the Python level.

Note: To fully benefit from inline_many, you should run your application on a multicore machine.

Configuration

For configuration options use the CSSInliner class:

import css_inline

inliner = css_inline.CSSInliner(keep_style_tags=True)
inliner.inline("...")
  • keep_style_tags. Specifies whether to keep "style" tags after inlining. Default: False
  • keep_link_tags. Specifies whether to keep "link" tags after inlining. Default: False
  • base_url. The base URL used to resolve relative URLs. If you'd like to load stylesheets from your filesystem, use the file:// scheme. Default: None
  • load_remote_stylesheets. Specifies whether remote stylesheets should be loaded. Default: True
  • extra_css. Extra CSS to be inlined. Default: None
  • preallocate_node_capacity. Advanced. Preallocates capacity for HTML nodes during parsing. This can improve performance when you have an estimate of the number of nodes in your HTML document. Default: 32

You can also skip CSS inlining for an HTML tag by adding the data-css-inline="ignore" attribute to it:

<head>
    <style>h1 { color:blue; }</style>
</head>
<body>
    <!-- The tag below won't receive additional styles -->
    <h1 data-css-inline="ignore">Big Text</h1>
</body>

The data-css-inline="ignore" attribute also allows you to skip link and style tags:

<head>
    <!-- Styles below are ignored -->
    <style data-css-inline="ignore">h1 { color:blue; }</style>
</head>
<body>
    <h1>Big Text</h1>
</body>

If you'd like to load stylesheets from your filesystem, use the file:// scheme:

import css_inline

# styles/email is relative to the current directory
inliner = css_inline.CSSInliner(base_url="file://styles/email/")
inliner.inline("...")

XHTML compatibility

If you'd like to work around some XHTML compatibility issues like closing empty tags (<hr> vs. <hr/>), you can use the following snippet that involves lxml:

import css_inline
from lxml import html, etree

document = "..."  # Your HTML document
inlined = css_inline.inline(document)
tree = html.fromstring(inlined)
inlined = etree.tostring(tree).decode(encoding="utf-8")

Performance

css-inline is powered by efficient tooling from Mozilla's Servo project and significantly outperforms other Python alternatives in terms of speed. It achieves over a 10x speed advantage compared to the next fastest alternative.

Here is the performance comparison:

css_inline 0.10.2 premailer 3.10.0 toronado 0.1.0 inlinestyler 0.2.5 pynliner 0.8.0
Basic 7.95 µs 197.08 µs (24.77x) 960.04 µs (120.64x) 1.52 ms (192.13x) 1.79 ms (225.64x)
Realistic-1 216.00 µs 2.09 ms (9.72x) 25.15 ms (116.47x) 42.75 ms (197.96x) 71.83 ms (332.59x)
Realistic-2 137.20 µs 3.98 ms (29.03x) ERROR 26.63 ms (194.15x) ERROR

The above data was obtained from benchmarking the inlining of CSS in HTML, as described in the Usage section. Note that the toronado and pynliner libraries both encountered errors when used to inline CSS in the last scenario.

The benchmarking code is available in the benches/bench.py file. The tests were conducted using the stable rustc 1.70 on Python 3.11.0.

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 and pynliner 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 optionally pynliner);
  • 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.

Further reading

If you want to know how this library was created & how it works internally, you could take a look at these articles:

License

This project is licensed under the terms of the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

css_inline-0.10.2.tar.gz (45.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

css_inline-0.10.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

css_inline-0.10.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

css_inline-0.10.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl (1.3 MB view details)

Uploaded PyPymacOS 10.7+ x86-64

css_inline-0.10.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

css_inline-0.10.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

css_inline-0.10.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl (1.3 MB view details)

Uploaded PyPymacOS 10.7+ x86-64

css_inline-0.10.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

css_inline-0.10.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

css_inline-0.10.2-pp37-pypy37_pp73-macosx_10_7_x86_64.whl (1.3 MB view details)

Uploaded PyPymacOS 10.7+ x86-64

css_inline-0.10.2-cp37-abi3-win_amd64.whl (1.3 MB view details)

Uploaded CPython 3.7+Windows x86-64

css_inline-0.10.2-cp37-abi3-win32.whl (1.2 MB view details)

Uploaded CPython 3.7+Windows x86

css_inline-0.10.2-cp37-abi3-musllinux_1_2_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.7+musllinux: musl 1.2+ x86-64

css_inline-0.10.2-cp37-abi3-musllinux_1_2_armv7l.whl (1.4 MB view details)

Uploaded CPython 3.7+musllinux: musl 1.2+ ARMv7l

css_inline-0.10.2-cp37-abi3-musllinux_1_2_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.7+musllinux: musl 1.2+ ARM64

css_inline-0.10.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.7+manylinux: glibc 2.17+ x86-64

css_inline-0.10.2-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (1.1 MB view details)

Uploaded CPython 3.7+manylinux: glibc 2.17+ ARMv7l

css_inline-0.10.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.7+manylinux: glibc 2.17+ ARM64

css_inline-0.10.2-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl (1.3 MB view details)

Uploaded CPython 3.7+manylinux: glibc 2.12+ i686

css_inline-0.10.2-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (2.5 MB view details)

Uploaded CPython 3.7+macOS 10.9+ universal2 (ARM64, x86-64)macOS 10.9+ x86-64macOS 11.0+ ARM64

css_inline-0.10.2-cp37-abi3-macosx_10_7_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.7+macOS 10.7+ x86-64

File details

Details for the file css_inline-0.10.2.tar.gz.

File metadata

  • Download URL: css_inline-0.10.2.tar.gz
  • Upload date:
  • Size: 45.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.6

File hashes

Hashes for css_inline-0.10.2.tar.gz
Algorithm Hash digest
SHA256 990fbf49c3c152f33e551e47faaf353c86af3df1dadda4cd0967d87ce63ed012
MD5 7a36366e2b855f782bada0a3fbb987ae
BLAKE2b-256 2b025d643783e74eb9e6facae2c6bc3647a619192a7ae061a5542897b3a992e9

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6e8056999bb88ed1cc437d9ccb1f01c6336ebebbcae09ebf33ee6f7c64c31ccd
MD5 483adb9b54407b66ded83065745f3b40
BLAKE2b-256 08021d856c607b797d99e277d745dbbc417b57da889ead33f7bd6bdc0a464aed

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 dcd5f4391647e38dce18f2a88dd174cfd43e89a3a6a986d0808264559da3267f
MD5 0b45b083adbb291aee972ab45933684c
BLAKE2b-256 77c65d8a3399acbfea0347c8d336f15c3c334ef19d17eaf25abc0e382d96a380

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 1eb6a8f8be762ae402fdcbe725f6691b41b06919ff09d1a83e89a19b28350b00
MD5 bacd2e7805fa2f322e506d6d069fe634
BLAKE2b-256 0d5f9a1360c7a83b892296e90a68c6d837007d0b2ee8c815f49f98f20d5d2b9e

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e2713dad735ef5af971243b5fac0eba59a3bee38b5e4f9dc8af05efad56b9c38
MD5 24e0f6f87cd41bd0327e771d09602a90
BLAKE2b-256 0607efa42a86d5afd2ef04aed420456ef2db42467a4c2d9c6df082e96c60138c

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5d4e39f6da50bbb31f26704f68644dbcfbd26185404f2d86233275164422d03a
MD5 33924504269e7ae74ec328702042b420
BLAKE2b-256 abf2fdb1acbf66421e01043ced3ef52456bdd6ef990fa41dd98e2c3342fb50bf

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 20b8ee848e3df77cd88eb657ca81c9422b68e68f9996f72d9d89293d945d148b
MD5 f2bb197382baadcd0b5f0ccf9a22a736
BLAKE2b-256 1a97379fb82caad315a7190c05e4294deb3da062d0c92ba42cea325772ef8f5a

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 20d66f42f7bb992da1c7dcc178ac91bd850567977dded1d428c41291058dcecc
MD5 a55639763b5c5f7783f32497dc80c487
BLAKE2b-256 0273a4db40c3e84b9e4f9ed440d398ce0759fa114bb07802a917237f0cd6ddc6

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 ed20b1dae052ec670b396ffaaa4f859e8f5ff429fb18a592bb06b505ce17c04d
MD5 e79a48725d03cb3b4185f305fbc58c10
BLAKE2b-256 d370d4581668a9bb07cbb260eb950b6ab671056e1129798ee7668cef3e71a594

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-pp37-pypy37_pp73-macosx_10_7_x86_64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-pp37-pypy37_pp73-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 01b94def2a11ca1b477378e585c786259f99cdada382a730446960dfafecaf61
MD5 4ef02b9e2d06515b82dca00fb025b19e
BLAKE2b-256 6def4cf2677a66f42d895e74664316c45bd44d4bbe031c5066f80c42ef433adf

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-cp37-abi3-win_amd64.whl.

File metadata

  • Download URL: css_inline-0.10.2-cp37-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.7+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.6

File hashes

Hashes for css_inline-0.10.2-cp37-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 2ea184df8a1fb0c2c506aab04a8ff8fbb4ddde68c7cc7f59257052b949e3249b
MD5 a7f053190803b8cd6aa3c85b5de58f55
BLAKE2b-256 7d6c9e4249e0d91508a0ae9aaa5c5274859917199a89ca91dc86f8a5075b7945

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-cp37-abi3-win32.whl.

File metadata

  • Download URL: css_inline-0.10.2-cp37-abi3-win32.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.7+, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.6

File hashes

Hashes for css_inline-0.10.2-cp37-abi3-win32.whl
Algorithm Hash digest
SHA256 bf1e09243d68127927dbeb11f3d2ecd08f3c51a50cb263f5bad7798017ac52b3
MD5 141c177dd7684b9feee9a01154423a50
BLAKE2b-256 2117c56ff84b60af7f98205cdc84a4d472680d3fd1b4bbdc281247994a1a18db

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-cp37-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-cp37-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 1ba30294ed149fe0791c1b7fa867fe07da53306f4506a7ef6266b8b5465b8f79
MD5 12b5c8a84dfb985f1b2cd465a4825f31
BLAKE2b-256 b64fcfcb42e9d5e857b8908eb1250a76c6f29d847c2d6a43ed7b0bf1be765cc3

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-cp37-abi3-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-cp37-abi3-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 74f77f64be3e236dc36c2b4a87ed16aff6a4d2dd52741967eef019bd2a334910
MD5 63a1397b5712497d92f7107c943ece22
BLAKE2b-256 21f41c1d614736f008935467016e6af47214904ba61d2e2d1db35a590c45da54

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-cp37-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-cp37-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 ae3c2db41d1173428e1f9ad01548148cbe9ab0de165428bf6ee7f940173dde3c
MD5 5a0656eee60221e9a2427bd9ed615e10
BLAKE2b-256 b82e984ff53d6071b6369e717325581d64362288dbb92dcb7e30b79000329742

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e7ca743cdea0b8407858b83cb9524b34d67d909ace536e9f0e0bef78fb955127
MD5 68552a6f01f69a98f1fdea1151ee86b2
BLAKE2b-256 5990dfb3cc9cc54f306224accf8e033feb04fd77b2af8df4ea65f5fda5616922

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 8431d7fd39481296f3ea5423f4c03065432ce5ccbed56f2e7cca364dbeeabb24
MD5 25220850f43d6c75bfd31bbc148e8dd5
BLAKE2b-256 b1ca07e420598cd1b7a3c0b01e379ce57059ea33fba9b29fc6fa13b10aff4415

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 54a3e9c192aeb9fff38394963e4bb6c65072dd6d99fcb39613ada96fdfe4cbf9
MD5 293c73167bd87eccdb3199ffd48500a0
BLAKE2b-256 fba80710495b11fc2f9de7183c27382616f75a0701625aa7a2b1d53b5473bebc

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 6666757aff4a23edbcb6984bbd709cae7d7a9b23080aaf150e8d93d1c5078cff
MD5 c440707fb56f3b694c2282c7212cb330
BLAKE2b-256 115ae52023fe0cfd7408086fd9522b4d596d4a1f0850fb50b6a3ce511e2266fe

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 64018f2188e138a8a0bc77f861eb695143a423b6cba771801939d9a9634957f3
MD5 403f56ca5e181f57cf307fd9eb09e6fc
BLAKE2b-256 039a21c8362944ee7e6307e4a02f581dee5e351b9c4a3c6df5c07d8756503004

See more details on using hashes here.

File details

Details for the file css_inline-0.10.2-cp37-abi3-macosx_10_7_x86_64.whl.

File metadata

File hashes

Hashes for css_inline-0.10.2-cp37-abi3-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 06375262ccecaf31558897a14f6f4f588110edb102db50b7a82eba7a70a5df89
MD5 e7d391132485630a9856f307f0d47dd0
BLAKE2b-256 bdd58c61db7a7cd94de193264b3c94452f4925dd96d27a53a17bd386f588c8d0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page