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 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
- 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
Playground
If you'd like to try css-inline
, you can check the WebAssembly-powered playground to see the results instantly.
Installation
Node.js
Install with npm
:
npm i @css-inline/css-inline
Usage
import { inline } from "@css-inline/css-inline";
var inlined = inline(
`
<html>
<head>
<style>h1 { color:red }</style>
</head>
<body>
<h1>Test</h1>
</body>
</html>
`,
);
Configuration
inlineStyleTags
. Specifies whether to inline CSS from "style" tags. Default: true
keepStyleTags
. Specifies whether to keep "style" tags after inlining. Default: false
keepLinkTags
. Specifies whether to keep "link" tags after inlining. Default: false
baseUrl
. The base URL used to resolve relative URLs. If you'd like to load stylesheets from your filesystem, use the file://
scheme. Default: null
loadRemoteStylesheets
. Specifies whether remote stylesheets should be loaded. Default: true
extraCss
. Extra CSS to be inlined. Default: null
preallocateNodeCapacity
. 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>
<h1 data-css-inline="ignore">Big Text</h1>
</body>
</html>
The data-css-inline="ignore"
attribute also allows you to skip link
and style
tags:
<head>
<style data-css-inline="ignore">h1 { color:blue; }</style>
</head>
<body>
<h1>Big Text</h1>
</body>
WebAssembly
css-inline
also ships a WebAssembly module built with wasm-bindgen
to run in browsers.
<script src="https://unpkg.com/@css-inline/css-inline-wasm"></script>
<script>
// Initialize the WASM module first
cssInline.initWasm(fetch('https://unpkg.com/@css-inline/css-inline-wasm/index_bg.wasm'));
const inlinedHtml = cssInline.inline(`<html>
<head>
<style>h1 { color:blue; }</style>
</head>
<body>
<h1>Big Text</h1>
</body>
</html>`);
document.getElementById('output').src = inlinedHtml
</script>
NOTE: WASM module currently lacks support for fetching stylesheets from network or filesystem.
Performance
css-inline
is powered by efficient tooling from Mozilla's Servo project and significantly outperforms other JavaScript alternatives in terms of speed.
Most of the time it achieves over a 4x speed advantage compared to the next fastest alternative.
Here is the performance comparison:
| Size | css-inline 0.12.0 | css-inline-wasm 0.12.0 | juice 10.0.0 | inline-css 4.0.2 |
---|
Basic | 230 B | 15.06 µs | 29.33 µs (1.94x) | 142.53 µs (9.46x) | 163.77 µs (10.87x) |
Realistic-1 | 8.58 KB | 320.71 µs | 638.97 µs (1.99x) | 1.28 ms (4.01x) | 1.87 ms (5.85x) |
Realistic-2 | 4.3 KB | 205.21 µs | 385.20 µs (1.87x) | 1.72 ms (8.42x) | 1.56 ms (7.63x) |
The "Basic" case was obtained from benchmarking the example from the Usage section.
The benchmarking code is available in the benches/bench.ts
file. The benchmarks were conducted using the stable rustc 1.74.1
on Node.js v21.4.0
.
License
This project is licensed under the terms of the MIT license.