Crate taffy

source ·
Expand description

Taffy

GitHub CI crates.io docs.rs

Taffy is a flexible, high-performance, cross-platform UI layout library written in Rust.

It currently implements the Flexbox and CSS Grid layout algorithms. Support for other paradigms is planned. For more information on this and other future development plans see the roadmap issue.

This crate is a collaborative, cross-team project, and is designed to be used as a dependency for other UI and GUI libraries. Right now, it powers:

  • Dioxus: a React-like library for building fast, portable, and beautiful user interfaces with Rust
  • Bevy: an ergonomic, ECS-first Rust game engine

Usage

use taffy::prelude::*;

// First create an instance of Taffy
let mut taffy = Taffy::new();

// Create a tree of nodes using `taffy.new_leaf` and `taffy.new_with_children`.
// These functions both return a node id which can be used to refer to that node
// The Style struct is used to specify styling information
let header_node = taffy
    .new_leaf(
        Style {
            size: Size { width: points(800.0), height: points(100.0) },
            ..Default::default()
        },
    ).unwrap();

let body_node = taffy
    .new_leaf(
        Style {
            size: Size { width: points(800.0), height: auto() },
            flex_grow: 1.0,
            ..Default::default()
        },
    ).unwrap();

let root_node = taffy
    .new_with_children(
        Style {
            flex_direction: FlexDirection::Column,
            size: Size { width: points(800.0), height: points(600.0) },
            ..Default::default()
        },
        &[header_node, body_node],
    )
    .unwrap();

// Call compute_layout on the root of your tree to run the layout algorithm
taffy.compute_layout(root_node, Size::MAX_CONTENT).unwrap();

// Inspect the computed layout using taffy.layout
assert_eq!(taffy.layout(root_node).unwrap().size.width, 800.0);
assert_eq!(taffy.layout(root_node).unwrap().size.height, 600.0);
assert_eq!(taffy.layout(header_node).unwrap().size.width, 800.0);
assert_eq!(taffy.layout(header_node).unwrap().size.height, 100.0);
assert_eq!(taffy.layout(body_node).unwrap().size.width, 800.0);
assert_eq!(taffy.layout(body_node).unwrap().size.height, 500.0); // This value was not set explicitly, but was computed by Taffy

Learning Resources

Taffy implements the Flexbox and CSS Grid specifications faithfully, so documentation designed for the web should translate cleanly to Taffy’s implementation. For reference documentation on individual style properties we recommend the MDN documentation (for example this page on the width property). Such pages can usually be found by searching for “MDN property-name” using a search engine.

If you are interested in guide-level documentation on CSS layout, then we recommend the following resources:

Flexbox

  • Flexbox Froggy. This is an interactive tutorial/game that allows you to learn the essential parts of Flebox in a fun engaging way.
  • A Complete Guide To Flexbox by CSS Tricks. This is detailed guide with illustrations and comphrehensive written explanation of the different Flexbox properties and how they work.

CSS Grid

  • CSS Grid Garden. This is an interactive tutorial/game that allows you to learn the essential parts of CSS Grid in a fun engaging way.
  • A Complete Guide To CSS Grid by CSS Tricks. This is detailed guide with illustrations and comphrehensive written explanation of the different CSS Grid properties and how they work.

Benchmarks (vs. Yoga)

  • Run on a 2021 MacBook Pro with M1 Pro processor using criterion
  • The benchmarks measure layout computation only. They do not measure tree creation.
  • Yoga benchmarks were run via the yoga crate (Rust bindings)
  • Most popular websites seem to have between 3,000 and 10,000 nodes (although they also require text layout, which neither yoga nor taffy implement).

Note that the table below contains multiple different units (milliseconds vs. microseconds)

BenchmarkNode CountDepthYoga (ba27f9d)Taffy (71027a8)
yoga ‘huge nested’1,0003364.60 µs329.04 µs
yoga ‘huge nested’10,00044.1988 ms4.3486 ms
yoga ‘huge nested’100,000545.804 ms38.559 ms
big trees (wide)1,0001737.77 µs505.99 µs
big trees (wide)10,00017.1007 ms8.3395 ms
big trees (wide)100,0001135.78 ms247.42 ms
big trees (deep)4,000122.2333 ms1.7400 ms
big trees (deep)10,000145.9477 ms4.4445 ms
big trees (deep)100,0001776.755 ms63.778 ms
super deep1,0001,000555.32 µs472.85 µs

Contributions

Contributions welcome: if you’d like to use, improve or build taffy, feel free to join the conversation, open an issue or submit a PR. If you have questions about how to use taffy, open a discussion so we can answer your questions in a way that others can find.

Re-exports

  • pub use crate::node::Taffy;

Modules

  • Axis enums representing CSS Grid axis
  • The Error types produced by Taffy.
  • Geometric primitives useful for layout
  • Final and cached data structures that represent the high-level UI layout
  • Contains numerical helper traits and functions
  • UI Node types and related data structures.
  • Commonly used types
  • A representation of CSS layout properties in Rust, used for flexbox layout
  • Helper functions which it make it easier to create instances of types in the style and geometry modules.
  • The baseline requirements of any UI Tree so Taffy can efficiently calculate the layout

Functions

  • Updates the stored layout of the provided node and its children