Java bindings for the high-performance css-inline library that inlines CSS into HTML 'style' attributes.
This library is designed for scenarios such as preparing HTML emails or embedding HTML into third-party web pages.
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
styleandlinktags - Removes
styleandlinktags - Resolves external stylesheets (including local files)
- Optionally caches external stylesheets
- Works on Linux, Windows, and macOS
- Supports HTML5 & CSS3
This package is available on GitHub Packages.
Maven Central publishing is in the works
GitHub Packages requires authentication even for public packages. See the GitHub documentation for authentication setup.
Gradle:
repositories {
maven {
url = uri("https://maven.pkg.github.com/Stranger6667/css-inline")
credentials {
username = project.findProperty("gpr.user") ?: System.getenv("USERNAME")
password = project.findProperty("gpr.key") ?: System.getenv("TOKEN")
}
}
}
dependencies {
implementation 'org.css-inline:css-inline:0.20.2'
}Maven:
<repositories>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/Stranger6667/css-inline</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.css-inline</groupId>
<artifactId>css-inline</artifactId>
<version>0.20.2</version>
</dependency>
</dependencies>See GitHub's Maven documentation for Maven authentication setup.
This JAR includes native libraries for the following platforms:
- Linux x86_64
- macOS x86_64
- macOS aarch64 (Apple Silicon)
- Windows x86_64
Requires Java 17+ with 64-bit JVM.
import org.cssinline.CssInline;
public class Example {
public static void main(String[] args) {
String html = """
<html>
<head>
<style>h1 { color:blue; }</style>
</head>
<body>
<h1>Big Text</h1>
</body>
</html>""";
String inlined = CssInline.inline(html);
System.out.println(inlined);
}
}To apply a CSS string directly to a document, use the inline(html, css) shortcut:
String inlined = CssInline.inline(html, "h1 { color: blue; }");You can also configure the inlining process:
import org.cssinline.CssInline;
import org.cssinline.CssInlineConfig;
public class ConfigExample {
public static void main(String[] args) {
String html = "...";
CssInlineConfig config = new CssInlineConfig.Builder()
.setLoadRemoteStylesheets(false)
.setKeepStyleTags(true)
.setBaseUrl("https://example.com/")
.build();
String inlined = CssInline.inline(html, config);
}
}setInlineStyleTags(boolean)- Inline CSS from<style>tags (default:true)setKeepStyleTags(boolean)- Keep<style>tags after inlining (default:false)setKeepLinkTags(boolean)- Keep<link>tags after inlining (default:false)setKeepAtRules(boolean)- Keepat-rules(starting with@) after inlining (default:false)setMinifyCss(boolean)- Remove trailing semicolons and spaces between properties and values (default:false)setBaseUrl(String)- Base URL for resolving relative URLs (default:null)setLoadRemoteStylesheets(boolean)- Load external stylesheets (default:true)setExtraCss(String)- Additional CSS to inline (default:null)setCacheSize(int)- External stylesheet cache size, must be ≥ 0 (default:0)setPreallocateNodeCapacity(int)- HTML node capacity, must be > 0 (default:32)setRemoveInlinedSelectors(boolean)- Remove selectors that were successfully inlined from<style>blocks (default:false)setApplyWidthAttributes(boolean)- AddwidthHTML attributes from CSSwidthproperties on supported elements (table,td,th,img) (default:false)setApplyHeightAttributes(boolean)- AddheightHTML attributes from CSSheightproperties on supported elements (table,td,th,img) (default:false)
Alternatively, you can inline CSS into an HTML fragment. Structural tags (<html>, <head>, <body>) are stripped from the output; only their contents are preserved. Use CssInline.inline if you need to keep the full document structure:
import org.cssinline.CssInline;
public class FragmentExample {
public static void main(String[] args) {
String fragment = """
<main>
<h1>Hello</h1>
<section>
<p>who am i</p>
</section>
</main>""";
String css = """
p {
color: red;
}
h1 {
color: blue;
}
""";
String inlined = CssInline.inlineFragment(fragment, css);
System.out.println(inlined);
}
}The inlineFragment method is useful when you have HTML snippets without a full document structure and want to apply specific CSS rules directly.
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>Alternatively, you may keep style from being removed by using the data-css-inline="keep" attribute.
This is useful if you want to keep @media queries for responsive emails in separate style tags.
Such tags will be kept in the resulting HTML even if the keep_style_tags option is set to false.
<head>
<!-- Styles below are not removed -->
<style data-css-inline="keep">h1 { color:blue; }</style>
</head>
<body>
<h1>Big Text</h1>
</body>Another possibility is to set keep_at_rules option to true. At-rules cannot be inlined into HTML therefore they
get removed by default. This is useful if you want to keep at-rules, e.g. @media queries for responsive emails in
separate style tags but inline any styles which can be inlined.
Such tags will be kept in the resulting HTML even if the keep_style_tags option is explicitly set to false.
<head>
<!-- With keep_at_rules=true "color:blue" will get inlined into <h1> but @media will be kept in <style> -->
<style>h1 { color: blue; } @media (max-width: 600px) { h1 { font-size: 18px; } }</style>
</head>
<body>
<h1>Big Text</h1>
</body>If you set the the minify_css option to true, the inlined styles will be minified by removing trailing semicolons
and spaces between properties and values.
<head>
<!-- With minify_css=true, the <h1> will have `style="color:blue;font-weight:bold"` -->
<style>h1 { color: blue; font-weight: bold; }</style>
</head>
<body>
<h1>Big Text</h1>
</body>css-inline is powered by efficient tooling from Mozilla's Servo project to provide high-performance CSS inlining for Java applications.
Here is the performance comparison:
| Size | css-inline 0.20.2 |
CSSBox 5.0.0 |
|
|---|---|---|---|
| Basic | 230 B | 7.22 µs | 53.33 µs (7.38x) |
| Realistic-1 | 8.58 KB | 109.77 µs | 1.60 ms (14.61x) |
| Realistic-2 | 4.3 KB | 61.92 µs | 381.42 µs (6.16x) |
| GitHub page | 1.81 MB | 23.17 ms | 312.22 ms (13.48x) |
The benchmarking code is available in the src/jmh/java/org/cssinline/CSSInlineBench.java file. The benchmarks were conducted using the stable rustc 1.91, OpenJDK 24.0.1 on Ryzen 9 9950X.
This project is licensed under the terms of the MIT license.