Yoga Layout Engine

repository·main·Indexed 12 days ago

https://github.com/react/yoga

An embeddable, high-performance flexbox layout engine written in C++ 20. Yoga provides layout calculations for various platforms and includes bindings for multiple programming languages, including a JavaScript/TypeScript implementation via the yoga-layout package.

Tokens
20.3K
Snippets
71
Records
100
Agent score
94%

What's inside Yoga

  1. What is Yoga and how does it work

    main

    Yoga is an embeddable layout engine designed to calculate the size and position of boxes. It is not a UI framework and does not perform any drawing or rendering.

    Key characteristics:

    • Layout Model: It implements a subset of CSS, primarily focused on the Flexbox layout model.
    • Responsibility: Its sole responsibility is determining the geometry (size and position) of layout nodes.
    • Implementation: It is written in C++ and exposes a public C API, making it compatible with many programming languages through various bindings (e.g., React Native).
  2. Configure Layout Conformance and Yoga Errata

    main

    Yoga can be configured with Errata to manage the trade-off between web standards compliance and backwards compatibility with older Yoga versions (like Yoga 1.x).

    By default, Yoga prefers standards compliance. If you are updating an existing application and find that layouts have broken due to Yoga's improved compliance, you can use Errata presets to restore previous behaviors.

    Errata Presets:

    1. None (Default): Prefers standards compliance.
    2. Classic: Operates as close as possible to Yoga 1.x.
    3. All: Enables Classic plus StretchFlexBasis (mapping to UseLegacyStretchBehaviour in Yoga 1.x).

    Note: Errata are configured as bit flags within the Yoga Config object.

    import Yoga, {Errata} from 'yoga-layout';
    
    const config = Yoga.Config.create();
    config.setErrata(Errata.Classic);
  3. Improved alignment for overflowed containers

    main

    Yoga 3.1 includes fixes for how flex children are aligned within overflowed containers. This specifically addresses issues when using justify-content, align-content, or margin: "auto", preventing scenarios where alignment keywords caused item overlapping or unintended padding removal.

    <Node
      style={{
        width: 100,
        height: 100,
        padding: 10,
        justifyContent: 'space-evenly',
      }}
    >
      <Node style={{height: 100, width: 100}} />
    </Node>
  4. Configure layout direction (LTR vs RTL)

    main

    Layout direction determines the direction in which children and text are laid out within a hierarchy. It also defines the meaning of the start and end logical properties.

    • LTR (Left-to-Right): The default mode. start refers to left and end refers to right. Text and children are laid out from left to right.
    • RTL (Right-to-Left): Used for localization in markets with right-to-left languages. start refers to right and end refers to left. Text and children are laid out from right to left.

    You can customize the direction by either passing a direction to the CalculateLayout call or by setting the direction property on a node's style.

    <Node
      style={{
        width: 200,
        height: 200,
        padding: 10,
        direction: 'ltr', // or 'rtl'
      }}
    >
      <Node style={{margin: 5, height: 50, width: 50}} />
      <Node style={{margin: 5, height: 50, width: 50}} />
    </Node>
  5. Use justifyContent to align children along the main axis

    main

    The justifyContent property defines how children are aligned within the main axis of their container. The behavior of the main axis depends on the flexDirection setting (e.g., horizontal for row, vertical for column).

    Available values:

    • flex-start (default): Aligns children to the start of the container's main axis.
    • flex-end: Aligns children to the end of the container's main axis.
    • center: Aligns children in the center of the container's main axis.
    • space-between: Evenly spaces children across the main axis, distributing remaining space between the children.
    • space-around: Evenly spaces children across the main axis, distributing remaining space around the children (includes space at the beginning of the first child and the end of the last child).
    • space-evenly: Distributes space such that the spacing between adjacent items, and the space between the edges and the first/last items, are all exactly equal.
    <Node
      style={{
        width: 200,
        height: 200,
        justifyContent: 'center', // Example: centers children
      }}
    >
      <Node style={{ width: 50, height: 50 }} />
      <Node style={{ width: 50, height: 50 }} />
    </Node>
  6. Understand Yoga's default styling behavior

    main

    Yoga nodes use styles similar to CSS, but they do not match web defaults by default. The standard Yoga defaults are:

    1. flex-direction: column (Web default is row)
    2. align-content: flex-start (Web default is stretch)
    3. flex-shrink: 0 (Web default is 1)
    4. position: relative (Web default is static)

    To make Yoga behave more like a web browser for flex-direction, align-content, and flex-shrink, you can configure Yoga using the UseWebDefaults flag.

    Note: UseWebDefaults does not change the default position to static to maintain compatibility with existing layouts.

  7. Configure the display property in Yoga

    main

    The display property in Yoga determines which layout specification a node follows and how it affects the layout tree.

    Yoga supports two primary values:

    • flex (default): Follows the CSS Flexible Box Model specification. This is the standard behavior for layout nodes.
    • none: The node is removed from the layout tree and will not be visible or occupy space in the layout.
    <Node
      style={{
        width: 200,
        height: 200,
        display: 'none' // This node will not be visible or affect layout
      }}
    />
    
    <Node
      style={{
        width: 200,
        height: 200,
        display: 'flex' // This node follows the Flexbox model
      }}
    />
  8. Understand absolute positioning errata in Yoga 3.2

    main

    Yoga 3.2 has removed the legacy absolute positioning path. It has replaced the old AbsolutePositioningIncorrect erratum with a more specific one to maintain compatibility while moving toward a more correct algorithm.

    • AbsolutePositioningIncorrect: This legacy erratum has been removed.
    • AbsolutePositionWithoutInsetsExcludesPadding: This is the new erratum. It preserves the specific compatibility quirk where previous incorrect behavior would omit padding when a position was not specified on an absolute node.

    Users of errata should expect more correct absolute positioning behavior while maintaining compatibility with existing codebases that relied on the specific padding quirk.

  9. Align children along the cross axis with align-items

    main

    The alignItems property defines how children are aligned along the cross axis of their container. This is distinct from justifyContent, which operates on the main axis.

    Available options:

    • stretch (default): Stretches children to match the size of the container's cross axis.
    • flex-start: Aligns children to the start of the cross axis.
    • flex-end: Aligns children to the end of the cross axis.
    • center: Aligns children to the center of the cross axis.
    • baseline: Aligns children along a common baseline.
    <Node
      style={{
        width: 200,
        height: 250,
        alignItems: 'flex-start',
      }}
    >
      {/* Children will be aligned to the start of the cross axis */}
    </Node>
  10. Override parent alignment for a single child with align-self

    main

    The alignSelf property allows you to change the alignment of an individual child within its parent container. It overrides the alignment behavior defined by the parent's alignItems property.

    Available options:

    • stretch
    • flex-start
    • flex-end
    • center
    • baseline
    <Node
      style={{
        width: 200,
        height: 250,
        alignItems: 'flex-start', // Parent sets default for all children
      }}
    >
      <Node
        style={{
          alignSelf: 'center', // This specific child overrides the parent to be centered
        }}
      />
      <Node /> {/* This child follows the parent's 'flex-start' alignment */}
    </Node>
  11. Use Flex Grow to distribute space

    main

    Flex Grow

    flexGrow determines how remaining space within a container is distributed among its children along the main axis after the initial layout is performed.

    • Value: Accepts any floating-point value $\ge 0$.
    • Default: 0.
    • Behavior: The container distributes remaining space among children weighted by their respective flexGrow values.
    <Node style={{ margin: 5, flexGrow: 0.25 }} />
    <Node style={{ margin: 5, flexGrow: 0.75 }} />
  12. Supported Units in Yoga

    main

    Yoga does not support CSS units like px or em. It operates using two types of values:

    1. Points: An absolute, canonical unit (typically mapped to device-independent pixels).
    2. Percentage: Relative to the parent node.

    If you are working with other CSS units (like em, rem, or vw), you must convert them to absolute points before passing them to Yoga.