css-inline 0.11.1

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

css-inline

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 crate 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
  • Inlines CSS from style and link tags
  • Removes style and link tags
  • Resolves external stylesheets (including local files)
  • Works on Linux, Windows, and macOS
  • Supports HTML5 & CSS3

Installation

To include it in your project, add the following line to the dependencies section in your project's Cargo.toml file:

[dependencies]
css-inline = "0.11"

The Minimum Supported Rust Version is 1.65.

Usage

const HTML: &str = r#"<html>
<head>
    <style>h1 { color:blue; }</style>
</head>
<body>
    <h1>Big Text</h1>
</body>
</html>"#;

fn main() -> Result<(), css_inline::InlineError> {
    let inlined = css_inline::inline(HTML)?;
    // Do something with inlined HTML, e.g. send an email
    Ok(())
}

Configuration

css-inline can be configured by using CSSInliner::options() that implements the Builder pattern:

const HTML: &str = "...";

fn main() -> Result<(), css_inline::InlineError> {
    let inliner = css_inline::CSSInliner::options()
        .load_remote_stylesheets(false)
        .build();
    let inlined = inliner.inline(HTML);
    // Do something with inlined HTML, e.g. send an email
    Ok(())
}
  • inline_style_tags. Specifies whether to inline CSS from "style" tags. Default: true
  • 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:

const HTML: &str = "...";

fn main() -> Result<(), css_inline::InlineError> {
    let base_url = css_inline::Url::parse("file://styles/email/").expect("Invalid URL");
    let inliner = css_inline::CSSInliner::options()
        .base_url(Some(base_url))
        .build();
    let inlined = inliner.inline(HTML);
    // Do something with inlined HTML, e.g. send an email
    Ok(())
}

Performance

css-inline typically inlines HTML emails within hundreds of microseconds, though results may vary with input complexity.

Benchmarks for css-inline==0.11.1:

  • Basic: 6.60 µs, 230 bytes
  • Realistic-1: 134.99 µs, 8.58 KB
  • Realistic-2: 93.56 µs, 4.3 KB
  • GitHub page: 329.99 ms, 1.81 MB

These benchmarks, conducted using rustc 1.74.0, can be found in css-inline/benches/inliner.rs.

Bindings

css-inline is primarily a Rust library, but we also provide bindings for several other languages:

Command Line Interface

Installation

Install with cargo:

cargo install css-inline

Usage

The following command inlines CSS in multiple documents in parallel. Resulting files will be saved as inlined.email1.html and inlined.email2.html:

css-inline email1.html email2.html

For full details of the options available, you can use the --help flag:

css-inline --help

Further reading

If you're interested in learning how this library was created and how it works internally, check out these articles:

Support

If you have any questions or discussions related to this library, please join our gitter!

License

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