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-400x 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.62.1 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. Most of the time it achieves over a 10x speed advantage compared to the next fastest alternative.

Here is the performance comparison:

Size css_inline 0.10.4 premailer 3.10.0 toronado 0.1.0 inlinestyler 0.2.5 pynliner 0.8.0
Basic 230 B 6.58 µs 130.45 µs (19.82x) 671.87 µs (102.06) 1.05 ms (161.00) 1.23 ms (187.51x)
Realistic-1 8.58 KB 146.20 µs 1.42 ms (9.71x) 16.56 ms (113.29x) 27.45 ms (187.78x) 51.85 ms (354.66x)
Realistic-2 4.3 KB 87.91 µs 2.71 ms (30.90x) ERROR 18.07 ms (205.64x) ERROR
GitHub page 1.81 MB 262.74 ms 25.38 s (96.63x) ERROR ERROR ERROR

The above data was obtained from benchmarking the inlining of CSS in HTML, as described in the Usage section. Note that the toronado, inlinestyler 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 benchmarks were conducted using the stable rustc 1.71.1 on Python 3.11.4.

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.5.tar.gz (48.6 kB view details)

Uploaded Source

Built Distributions

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

Uploaded PyPy manylinux: glibc 2.17+ x86-64

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

Uploaded PyPy manylinux: glibc 2.17+ ARM64

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

Uploaded PyPy macOS 10.7+ x86-64

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

Uploaded PyPy manylinux: glibc 2.17+ x86-64

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

Uploaded PyPy manylinux: glibc 2.17+ ARM64

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

Uploaded PyPy macOS 10.7+ x86-64

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

Uploaded PyPy manylinux: glibc 2.17+ x86-64

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

Uploaded PyPy manylinux: glibc 2.17+ ARM64

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

Uploaded PyPy macOS 10.7+ x86-64

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

Uploaded CPython 3.7+ Windows x86-64

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

Uploaded CPython 3.7+ Windows x86

css_inline-0.10.5-cp37-abi3-musllinux_1_2_x86_64.whl (1.6 MB view details)

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

css_inline-0.10.5-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.5-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.5-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.5-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (1.2 MB view details)

Uploaded CPython 3.7+ manylinux: glibc 2.17+ ARMv7l

css_inline-0.10.5-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.5-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl (1.4 MB view details)

Uploaded CPython 3.7+ manylinux: glibc 2.12+ i686

css_inline-0.10.5-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (2.6 MB view details)

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

css_inline-0.10.5-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.5.tar.gz.

File metadata

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

File hashes

Hashes for css_inline-0.10.5.tar.gz
Algorithm Hash digest
SHA256 acc3236360b858ec39c0e4d670470f53ab1db20165653a6d8e12ef2cb21905d6
MD5 4d3d6cb86a5ff4d636ab74ac27db1815
BLAKE2b-256 b2ec7c5222d5b10f0ea00787fdea08efc5668293c9d4fb808d2335617069ff36

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f568df198a0e8ca523b1041fb3cffd2a8d7920de822ee79cc60420a8426cb78d
MD5 7fd93e8227e52b53e0d4cbfe7284a415
BLAKE2b-256 bc761ef0f87c538f76a2af97b7f0c10b00a88a72d5af2fcd16bdea8babbb4e00

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 44b22b8d297551422661b5381c42f1562d41273afb262d572052abe2c7a08445
MD5 425948b4489dd4cd5e63cd086ff95297
BLAKE2b-256 0d75d9c05a8a1b2785cb21670c19279eef8be595efb1a62abc3c655a597554b1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-pp39-pypy39_pp73-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 bde58c0d55e56a31debce44761776484dbc333dfaf7967cabc07121fe45596a8
MD5 6791a07384ff4e232fd6ae372c44dc55
BLAKE2b-256 04e0b8b03736d05f6f2d4095570aca4de05f5ebc52a108c83b2e1377ecae7b0e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b5a5d63a40d497bcf825dd23d4501187c5e67e7b1849f577b7fc913830e38b3c
MD5 ee583070603f549a3caaca4b8d499289
BLAKE2b-256 502e130db6edb124b93cb8b581074b5d13c7b7472871ff0d2c73e039e4b5b50d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 b93b1b51a231575e45f6e5680bfdb5a831dbb5acc28412b7aa0d9ee1b41c5ff5
MD5 677da7fcd5252239865de00ffd9fc759
BLAKE2b-256 d50912773a0c9ba7211be63220ceb6939f360f4b793fec28ee72c36f3c2669f7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-pp38-pypy38_pp73-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 fc5370b5aa1edbe8dade284561966d48cc84b6f3b23045e143fc90993b304513
MD5 64ebe224f65c1772fef823d809930f19
BLAKE2b-256 fddf58f65b4308b8a1984c57bf480b0b89b6a7703f7d907fdda0328accc2ae85

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3da6cfd5cbaebe1cf94478f943e1cb7f988f260197a0ed1b6e8f117d5806e17a
MD5 4ecc36cbcaae68260b910e5b32225f15
BLAKE2b-256 77f2db9f1f639a26a16bc951de3f01c64085afcc5788ee25a69a3a31ba2ad2e1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6255930a9d876d5f457489892affa8f68edf570a90935240d02389d11622bd78
MD5 9f1aa2fd00c619f9662ad8d9af83e1ec
BLAKE2b-256 2595eacc0ba799c55d21734738e9142b4d121997917cfb06c4db63f4949681a3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-pp37-pypy37_pp73-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 3f43b320ff90a18aa43196065fd09909a491cff0c1506afd2b2df9509f00410b
MD5 bf7a9810ce5b6592b5c40b1fbdd39bb4
BLAKE2b-256 52e422e1c277ffcb769f7631165c87504ebb73d486149498a3c7fa0bd0ac4eff

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-cp37-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 90f1e1039fa57b5e55d6173739f2596f772ffb2495448927375d622bdca24bac
MD5 e8475027c6556ef6de16af24d8e88111
BLAKE2b-256 6328b0525c937b82e41d3e531d1d5eb08bce7c4983508caee8083d60bdf8f5b8

See more details on using hashes here.

File details

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

File metadata

  • Download URL: css_inline-0.10.5-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.12

File hashes

Hashes for css_inline-0.10.5-cp37-abi3-win32.whl
Algorithm Hash digest
SHA256 92ba60ac6592bd0b03b667e1b96e46824d46828a28699737d432034160c02b65
MD5 cc1553134b0267a1acf215347a0b7b4c
BLAKE2b-256 53238f7d227732b2cf3d561cd79e9f3d427d1cdc39d693b46b36d1d91713b55e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-cp37-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 e92f6b2cd863c275f9bd968d876fe92cb3296371403c3970f3c4e8d710eed36a
MD5 9f3061d885eb1e60b09cf68e8aecb012
BLAKE2b-256 1990aee7c368aac51e4b02b87b319c74a2fcfa75397709245916dc042f1338fb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-cp37-abi3-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 cb272be588096e7ea4476e6cd196fd8a7e4aac375a8b48b70294d66b008760bd
MD5 e7a8b8202fa19c6dd8a47f61d2e30ddc
BLAKE2b-256 74e9f5004a90d0d3a8c12cfd59b67fdde273a84ec0e45f4820ce9ad5ed1f8533

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-cp37-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 7dcd7d71c28314c95f24cb60f27b47903431d880285ff48811a8c8dee5ab4568
MD5 77533c07e856abd92577d3c5ccb96e37
BLAKE2b-256 2428078f46de046dda46849a5ac0b61cf1abeb5bda78d9dcd38dc85858ab75ca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a10456873483ea4cc47b07c5486a327d64affa074a1010ec8801d1bd5bcc7a8a
MD5 857827089e2728c072a0df60e9567564
BLAKE2b-256 9f1fb12ed8fe2572d0d3eeba269f6c0fd76867b9f9481aee767e54d460e3d67f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 568e9816509a98000bda8cbf5f8c82c683c7a6ae096026ceb614339709b4ca68
MD5 dc8e0e74f86a7d675ab3c6b132544920
BLAKE2b-256 2a5640fe7e4faa50d7393c193ffc26b9b6ea409540dcd25b19e06517cb8b9929

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e8b3caf3360df477bdf662e242549cd214c5201b6515b79e0e5ae007747eb87f
MD5 73ec97ab17c75d5a0be7643fcf4186c7
BLAKE2b-256 0da067a68d450312140f51474fcb71eb42fc5673eb6e0f0a1b5e71a1380836c5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 fd991c3f2f5ab9bb27bc1a7312305e1a19e7e6add173f1c1b40f8e686c6738a1
MD5 05faeafaef22b1497d01c0befb75b415
BLAKE2b-256 72770d0012aa6c4049d0190cd21c4dd74d0ba5bf4bc4f3d12c3d33c1f8e6f444

See more details on using hashes here.

File details

Details for the file css_inline-0.10.5-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.5-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 3b83aab29e524947760f9696ebc57b1dc1cdfc1138d98dfb2ffeea437dc0d060
MD5 c2095c06e67ee069e1fff230eb097632
BLAKE2b-256 6c05b620e95dfa45f34e77373de18bf4f4762c442abf184d4db477765f8f95ad

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for css_inline-0.10.5-cp37-abi3-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 e1e95ec41dff79f7bc1db0589bd1c43bcf8dddbcf05b41231311c718b34fcf8f
MD5 62f3e1a34391933490426edeb678753e
BLAKE2b-256 ee8dceaca4cd3f51390ba863c1da4f43abebabf780c79904d50c7509f1e82833

See more details on using hashes here.

Supported by

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