A toy browser rendering engine written in Rust that parses HTML and CSS, applies styling, performs layout calculations, and renders the result to a PNG image.
This project is based on the excellent tutorial series "Let's build a browser engine!" by Matt Brubeck.
This browser engine implements a simplified rendering pipeline that transforms HTML and CSS into a visual representation. The engine follows the standard browser rendering pipeline:
- HTML Parsing - Parses HTML into a DOM tree
- CSS Parsing - Parses CSS rules and declarations
- Style - Matches CSS rules to DOM nodes and builds a style tree
- Layout - Calculates the position and size of each element (block layout)
- Painting - Rasterizes the layout tree into pixels and outputs a PNG image
- ✅ HTML parsing into DOM tree
- ✅ CSS parsing (selectors, declarations, values)
- ✅ Style tree construction with rule matching
- ✅ Block-level layout algorithm
- ✅ Basic painting/rasterization
- ✅ Background color rendering
- ✅ Border rendering
- ✅ Padding support
- ✅ Nested block elements
- ✅ PNG output
- ✅ Alpha channel support and transparency blending
- ✅ Hex color parsing with alpha channel (#rrggbbaa format)
- ✅ RGB function support with optional alpha channel (
rgb(r, g, b)andrgb(r, g, b / alpha)) - ✅ Inline CSS styles via HTML
styleattribute
The project is organized into several modules:
dom.rs- DOM node structure and tree representationhtml.rs- HTML parsercss.rs- CSS parser and value typesstyle.rs- Style tree construction and CSS rule matchinglayout.rs- Block layout algorithm and box model calculationspainting.rs- Display list generation and rasterization
- Rust (latest stable version recommended)
- Cargo
cargo buildThe program accepts command-line arguments for HTML and CSS files:
cargo run -- --html <html_file> --css <css_file> --output <output_file>Default behavior (if no arguments provided):
- HTML:
./test.html - CSS:
./test.css - Output:
./output.png
Example:
cargo run -- -html test.html -css test.css -output result.pngtest.html:
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<div class="a">
<div class="b">
<div class="c">
<div class="d">
<div class="e">
<div class="f">
<div class="g"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>test.css:
* {
display: block;
padding: 12px;
}
.a {
background: #ff0000;
}
.b {
background: #ffa500;
}
.c {
background: #ffff00;
}
.d {
background: #008000;
}
.e {
background: #0000ff;
}
.f {
background: #4b0082;
}
.g {
background: #800080;
}This will produce a PNG image with nested colored rectangles.
Color Formats:
You can use hex colors with alpha channel by using 8 hex digits instead of 6:
.semi-transparent {
background: #ff000080; /* Red with 50% opacity (128/255) */
}You can also use the rgb() function with optional alpha channel:
.red {
background: rgb(255, 0, 0); /* Opaque red */
}
.semi-transparent-blue {
background: rgb(0, 0, 255 / 0.5); /* Blue with 50% opacity */
}The alpha value in rgb() should be a float between 0.0 (fully transparent) and 1.0 (fully opaque). The engine performs alpha compositing, blending semi-transparent colors with the background colors underneath them.
Inline Styles:
You can use inline CSS styles directly in HTML elements using the style attribute:
<div style="background: #00ff00; padding: 20px;">
This div has an inline style
</div>Inline styles have higher specificity than stylesheet rules and will override matching CSS rules.
getopts- Command-line argument parsingimage- PNG image encoding
The following features are planned for future implementation:
- Cascading - Proper CSS cascade order and specificity resolution
- Initial and/or computed values - Default values for CSS properties
- Inheritance - CSS property inheritance from parent to child elements
- Collapsing vertical margins - CSS margin collapsing behavior
- Text rendering - Rendering text on screen
- Only supports block-level layout (no inline layout yet)
- No support for many CSS properties
- No z-index support
- Simplified CSS selector matching
- No support for CSS inheritance or cascading
This project is based on the tutorial series by Matt Brubeck:
- Part 1: Getting started
- Part 2: HTML
- Part 3: CSS
- Part 4: Style
- Part 5: Boxes
- Part 6: Block layout
- Part 7: Painting 101
This is an educational project based on the tutorial series mentioned above.