Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

css-inline

build status github packages

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>

Features

  • 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)
  • Optionally caches external stylesheets
  • Works on Linux, Windows, and macOS
  • Supports HTML5 & CSS3

Installation

This package is available on GitHub Packages.

Maven Central publishing is in the works

Setup

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.

Platform Support

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.

Usage

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) - Keep at-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) - Add width HTML attributes from CSS width properties on supported elements (table, td, th, img) (default: false)
  • setApplyHeightAttributes(boolean) - Add height HTML attributes from CSS height properties on supported elements (table, td, th, img) (default: false)

HTML Fragments

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.

Special Attributes

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>

Performance

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.

License

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