English · 简体中文
A C++20 layout library for native UI
Block · Flexbox · Grid
Quick start · Layout guide · Examples · Benchmarks · Changelog
Axisly turns layout trees, styles, and content measurements into widget positions and sizes. Your host provides windows, widgets, text measurement, and rendering. Axisly computes the geometry for an existing UI framework or a custom interface.
- Framework independent: the core uses only the C++ standard library and ships as a static library. A normal build downloads no third-party dependencies.
- Composable layouts: nest Block, Flexbox, and Grid in one tree with shared sizing, measurement, and alignment rules.
- Incremental updates: retain the tree and reuse unchanged results through dirty tracking and measurement and layout caches.
- Flexible integration: let Axisly manage the tree or adapt an existing host tree, with per-node queries, reusable memory, and batch computation of independent trees.
| Layout | Capabilities |
|---|---|
| Block / FlowRoot | Block flow, floats and clear, independent formatting contexts |
| Flexbox | Rows and columns, grow and shrink, wrapping, reverse directions, baseline alignment, and balanced wrapping |
| Grid | Explicit and implicit tracks, auto-placement, spans, named lines, template areas, minmax, and automatic repetition |
All three layouts share fixed and percentage sizes, min/max-content sizing, typed calc values, box-model and aspect-ratio constraints, relative and absolute positioning, bidirectional alignment, scroll extents, reserved scrollbar space, and optional device-pixel rounding. See the layout guide and compatibility matrix for individual fields and behavior limits.
Requires a C++20 compiler and CMake 3.25+.
Download the source ZIP or tar.gz from GitHub Releases. Each release includes SHA-256 checksums. Build the library with the compiler and configuration used by your application.
Place the source in your project, for example at third_party/axisly, and link the exported target:
add_subdirectory(third_party/axisly)
target_link_libraries(your_app PRIVATE axisly::axisly)Tests and examples are disabled by default when Axisly is included as a subproject.
Use an installed CMake package
Add the installation prefix to CMAKE_PREFIX_PATH and link the same target:
find_package(axisly CONFIG REQUIRED)
target_link_libraries(your_app PRIVATE axisly::axisly)See the build guide for installation steps.
Style::display defaults to Flex with a horizontal main axis. Set Display::Block explicitly for block layout.
This example creates two flexible items in a row, in a container of width 320 with a gap of 8:
#include <axisly/css_tree.hpp>
#include <cstdio>
int main() {
namespace css = axisly::css;
css::LayoutTree tree;
css::Style row;
row.display = css::Display::Flex;
row.box.size = {css::Length::length(320), css::Length::length(48)};
row.gap.width = css::Length::length(8);
const auto root = tree.create_node(row);
css::Style item;
item.box.size = {css::Length::length(80), css::Length::length(24)};
item.flex_grow = 1;
tree.append_child(root, tree.create_node(item));
tree.append_child(root, tree.create_node(item));
const auto& result = tree.compute(root, {
css::AvailableSpace::definite(320),
css::AvailableSpace::definite(48)});
if (!result.succeeded()) return 1;
for (const auto& node : result.nodes) {
if (node.node == root) continue;
const auto& r = node.border_box;
std::printf("%.0f %.0f %.0f %.0f\n", r.x, r.y, r.width, r.height);
}
}Each output line contains x y width height:
0 0 156 24
164 0 156 24
- Apply each returned rectangle to its widget. Coordinates in the example are relative to the layout root.
- Supply a measurement callback through
create_node(style, measure)for text, images, and other content. - Call
mark_dirty(node)after content changes.set_style(node, style)automatically invalidates affected cached results.
The tree owns the result, and subsequent computations update it. Copy results that need to survive across frames.
See the CSS layout guide for measurement contracts, error handling, and host integration.
| Approach | When to use it | API |
|---|---|---|
| Axisly owns the layout tree | Let the library manage nodes, styles, caches, and incremental invalidation | LayoutTree |
| Adapt an existing host tree | Connect an existing widget tree and style system to the layout engine | LayoutSource / LayoutSession |
Both approaches share the same CSS Block, Flexbox, and Grid semantics. Grid uses Style::grid,
TrackSizing, and GridLine; nested grids are ordinary child nodes in the same tree.
Layout-tree and style APIs live in axisly::css. Include individual headers as needed,
or use the umbrella header <axisly/axisly.hpp>.
| Example | What it demonstrates | Entry point |
|---|---|---|
| Console example | Tracks, measurement, spans, alignment, nesting, caching, and rounding | Source |
| SDL3 Playground | Resize the canvas and inspect grid lines, item borders, and final rectangles | Run guide |
| GeeyoouUI Showcase | Windows host integration across 19 pages, including forms, tables, and themes | Run guide |
Graphical examples are optional development targets; their UI and rendering dependencies stay outside the core library. Follow the host integration steps to connect measurement, invalidation, and rectangle application in another framework.
CSS layout uses Taffy 0.14.0 as its versioned compatibility reference, with differential checks against fixed cases, property combinations, and the upstream corpus. Known differences between Taffy and browser specifications are documented in the compatibility guide.
The library accepts typed C++ styles. CSS string parsing, selectors, the cascade, DOM, text shaping, and rendering are outside its scope, as are browser features such as inline formatting, table layout, vertical writing, and pagination. Scroll extents are layout output; the host implements scrolling and clipping.
The current release is 0.2.0. Source and binary compatibility across versions is not guaranteed. Rebuild all consumers when upgrading and review the changelog and migration notes.
Detailed guides and the changelog are currently available in Simplified Chinese.
| Guide | Contents |
|---|---|
| Build guide | Compilation, installation, and CMake options |
| CSS layout guide | Styles, measurement, updates, and result lifetime |
| Execution resources | Memory reuse, batch execution, rounding, and PGO |
| Compatibility matrix | Layout field mapping and scope |
| Specification differences | Independent specification cases, browser replays, and known differences |
| Examples | Console, SDL3, and GeeyoouUI examples |
| Testing | Contract tests, upstream replay, and sanitizers |
| Benchmarks | Comparing Axisly, Taffy, and Yoga with identical input |
Core implementation lives in src and public interfaces in include/axisly. Reference implementations, benchmark tools, and graphical examples are optional development dependencies.