Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cssbox

CI Crates.io docs.rs License: MIT Docs

A standalone CSS layout engine in Rust. HTML/CSS in, exact coordinates out.

Built for PDF generation, document rendering, native UI, and anywhere you need CSS layout without a browser.


The Problem

If you need to lay out a document with CSS — generate a PDF from HTML, render rich text in a native app, build an e-book reader — your options are:

  • Headless Chrome/Puppeteer — works, but it's a 200MB dependency that spawns a browser process
  • WeasyPrint — Python-only, slow, flexbox/grid support is incomplete
  • Prince XML — proprietary, expensive
  • wkhtmltopdf — deprecated and unmaintained

Libraries like Yoga and Taffy are great for app-style UI (flexbox/grid), but they don't handle document-style layout — inline text flow, floats, tables, or the CSS cascade. They solve a different problem.

cssbox fills the gap: a fast, embeddable Rust library that handles the full CSS layout spec, from modern flexbox/grid to traditional document flow.

Getting Started

[dependencies]
cssbox-core = "0.1"
use cssbox_core::tree::BoxTreeBuilder;
use cssbox_core::style::ComputedStyle;
use cssbox_core::geometry::Size;
use cssbox_core::layout::{compute_layout, FixedWidthTextMeasure};
use cssbox_core::values::LengthPercentageAuto;

// Build a tree of styled nodes
let mut builder = BoxTreeBuilder::new();
let root = builder.root(ComputedStyle::block());

let mut child_style = ComputedStyle::block();
child_style.width = LengthPercentageAuto::px(200.0);
child_style.height = LengthPercentageAuto::px(100.0);
let child = builder.element(root, child_style);

let tree = builder.build();

// Compute layout against an 800x600 viewport
let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(800.0, 600.0));

// Query the result — just like getBoundingClientRect()
let rect = result.bounding_rect(child).unwrap();
assert_eq!(rect.width, 200.0);
assert_eq!(rect.height, 100.0);

From HTML/CSS

use cssbox_dom::computed::html_to_box_tree;
use cssbox_core::geometry::Size;
use cssbox_core::layout::{compute_layout, FixedWidthTextMeasure};

let tree = html_to_box_tree(r#"
    <div style="display: flex; gap: 10px">
        <div style="flex: 1; height: 100px"></div>
        <div style="flex: 2; height: 100px"></div>
    </div>
"#);

let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(800.0, 600.0));

What It Supports

cssbox implements 7 CSS layout modes — both the modern layout primitives (flexbox, grid) and the traditional document flow (block, inline, float) that document rendering requires.

Algorithm Spec What it covers
Block CSS 2.1 §9.4.1 Width/height determination, margin collapsing, box-sizing, min/max constraints, percentages
Inline CSS 2.1 §9.4.2 Line box construction, greedy line breaking, text-align, vertical-align, white-space
Float CSS 2.1 §9.5.1 Left/right placement, exclusion zones, clear, BFC containment
Positioning CSS 2.1 §9.3 relative, absolute, fixed, sticky, constraint solving, stretch
Flexbox Flex Level 1 Direction, wrapping, grow/shrink, all alignment and spacing modes
Grid Grid Level 2 Track sizing (fr, minmax(), fit-content()), auto-placement, gap
Table CSS 2.1 §17 Fixed and auto layout, border-collapse/border-spacing, captions

Landscape

Existing embeddable layout libraries are purpose-built for app UI (flexbox/grid) and intentionally skip document layout. Full browsers handle everything but aren't embeddable. cssbox sits in the middle.

Embeddable libraries

Engine Language Stars Document layout App layout
Yoga C++ 18.7k — Flexbox
Taffy Rust 3k Block only Flexbox, Grid
Dropflow TS/Zig 1.4k Block, Inline, Float —
cssbox Rust — Block, Inline, Float, Table Flexbox, Grid

Full browsers and renderers (not embeddable as libraries)

Engine Notes
Servo Rust browser engine. Uses Taffy for flex/grid. Inline/float still incomplete (18-52% WPT).
NetSurf C browser. Strong CSS 2.1 + flexbox. No grid.
Ladybird C++ browser. Pre-alpha. Targeting full CSS.
WeasyPrint Python PDF renderer. Best document layout coverage, but flexbox/grid marked "not deeply tested".

Use Cases

  • PDF / document generation — HTML/CSS to precise coordinates, then render to PDF
  • Rich text UI — document-style layout in native apps (editors, readers, email clients)
  • Native UI — CSS layout without a webview
  • Embedded devices — small footprint, zero runtime dependencies
  • Testing tools — verify CSS layout behavior programmatically

Crate Structure

Crate Description
cssbox-core Core layout algorithms. Zero dependencies, no_std compatible.
cssbox-dom HTML/CSS parsing, selector matching, cascade, computed values.
cssbox-test-harness WPT test infrastructure (reftest + testharness.js).

Text Measurement

cssbox doesn't measure text — you provide the font metrics via a trait:

pub trait TextMeasure {
    fn measure(&self, text: &str, font_size: f32, max_width: f32) -> Size;
}

A built-in FixedWidthTextMeasure (8px/character) is included for testing. For production, plug in your font rasterizer (e.g., rusttype, fontdue, cosmic-text).

Testing

cargo test --workspace              # all 97 tests
cargo test -p cssbox-core           # core layout tests
cargo test -p cssbox-core block     # specific algorithm
cargo test -p cssbox-core flex
cargo test -p cssbox-core grid

Contributing

Contributions are welcome! The biggest impact areas:

  1. WPT pass rate — pick a failing test, fix the layout algorithm
  2. Missing CSS properties — add parsing + layout support
  3. Text shaping — improve inline layout with real text measurement
  4. Performance — layout caching, incremental relayout

License

MIT

About

Fast embeddable Rust CSS layout engine for document rendering without a browser.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages