# Technical Documentation: react/yoga

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/react/yoga)

### Overview (`README.md`)

# Yoga [](https://www.npmjs.com/package/yoga-layout) [](https://search.maven.org/artifact/com.facebook.yoga/yoga) 

Yoga is an embeddable and performant flexbox layout engine with bindings for multiple languages.

## Building

Yoga's main implementation targets C++ 20 with accompanying build logic in CMake. A wrapper is provided to build the main library and run unit tests.

```sh
./unit_tests Debug
./unit_tests Release
```

While not required, this script will use [ninja](https://ninja-build.org/) if it is installed for faster builds.

Yoga is additionally part of the [vcpkg](https://github.com/Microsoft/vcpkg/) collection of ports maintained by Microsoft and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.

## Adding Tests

Many of Yoga's tests are automatically generated, using HTML fixtures describing node structure. These are rendered in Chrome to generate an expected layout result for the tree. New fixtures can be added to `gentest/fixtures`.

```html
<div id="my_test" style="width: 100px; height: 100px; align-items: center;">
  <div style="width: 50px; height: 50px;"></div>
</div>
```

To generate new tests from added fixtures:

1. Ensure you have [yarn classic](https://classic.yarnpkg.com) installed.
2. Run `yarn install` to install dependencies for the test generator.
3. Run `yarn gentest` in the `yoga` directory.

## Debugging

Yoga provides a VSCode "launch.json" configuration which allows debugging unit tests. Simply add your breakpoints, and run "Debug C++ Unit tests (lldb)" (or "Debug C++ Unit tests (vsdbg)" on Windows).

---

### Overview (`javascript/README.md`)

# yoga-layout

This package provides prebuilt WebAssembly bindings for the Yoga layout engine.

See more at https://yogalayout.dev

## Usage

```ts
import {Yoga, Align} from 'yoga-layout';

const node = Yoga.Node.create();
node.setAlignContent(Align.Center);
```

## Requirements

`yoga-layout` requires a toolchain that supports ES Modules and top-level await.

If top-level-await is not supported, use the `yoga-layout/load` entry point instead. This requires to load yoga manually:

```ts
import {loadYoga, Align} from 'yoga-layout/load';

const node = (await loadYoga()).Node.create();
node.setAlignContent(Align.Center);
```

---

### Overview (`website/README.md`)

# Website

This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.

### Installation

```
$ yarn
```

### Local Development

```
$ yarn start
```

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

### Build

```
$ yarn build
```

This command generates static content into the `build` directory and can be served using any static contents hosting service.

### Deployment

Using SSH:

```
$ USE_SSH=true yarn deploy
```

Not using SSH:

```
$ GIT_USER=<Your GitHub username> yarn deploy
```

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

---

### Styling Index (`website/docs/styling/index.md`)

---
sidebar_position: 2
---

# Styling

Each Yoga node has an associated style. Nodes may be styled using similar properties to CSS, with some caveats.

## Default styles

The default Yoga node style is similar to a box on web set to `display: flex`, with a few notable exceptions:

1. `flex-direction` defaults to `column` instead of `row`
2. `align-content` defaults to `flex-start` instead of `stretch`
3. `flex-shrink` defaults to `0` instead of `1`
4. `position` defaults to `relative` instead of `static`

Yoga may be [configured](../getting-started/configuring-yoga.mdx) to align to the defaults on web for `flex-direction`, `align-content`, and `flex-shrink` by setting the `UseWebDefaults` flag.

:::warning

Because `UseWebDefaults` was established before the introduction of `position: 'static'`, it does not change the default `position`, in order to preserve compatibility.

:::

## Box Sizing

Yoga acts as if [`box-sizing: 'border-box'`](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing) is set. This means that specified dimensions for a box will include the space taken for padding and border.

## Edges

Margin, padding, position, and border, are set against an Edge, which may be:

1. Relative to writing direction (start/end)
2. A physical edge (top/right/left/bottom)
3. A collection of edges (vertical/horizontal/all)

A style value may be set against multiple Edge values at once, with precedence given in the above order.

## Units

Yoga does not operate on CSS units like `px` or `em`. Yoga instead works on "points", representing an arbitrary, canonical absolute unit (usually mapped to display independent pixels), along with percentage. Other units should be absolutized before being given to Yoga.

## Non-standard properties

Yoga's `aspect-ratio` property was added before the same property was added to CSS, and may act subtlety different. These differences may be reconciled in a future version of Yoga.

Yoga's `flex` shorthand will act as `flex-grow` if positive, or `flex-shrink` if negative.

---

### About Yoga (`website/docs/about-yoga.md`)

---
sidebar_position: 1
---

# About Yoga

Yoga is an embeddable layout system used in popular UI frameworks like React Native. Yoga itself is not a UI framework, and does not do any drawing itself. Yoga's only responsibility is determining the size and position of boxes.



Yoga supports a familiar subset of CSS, mostly focused on Flexbox. This gives users a familiar model, and enables sharing code between native platforms and the browser.

Yoga is written in C++, with a public C API. This allows Yoga to be used by a wide variety of languages, via both official and unofficial bindings.

---

### Advanced Containing Block (`website/docs/advanced/containing-block.md`)

---
sidebar_position: 2
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Playground from '@site/src/components/Playground';

# Containing block

Often times certain properties depend on a node beyond the
one it is applied to. An example of this is percentage lengths like `width: 50%` which
will set the width of a node to 50% of some other length. That other length is determined
by the size of the _containing block_. A containing block is not a Yoga-specific
concept and exists in the [web](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block),
but since Yoga only implements a subset of web browser capabilities the behavior of
containing blocks is much more streamlined and it is helpful to frame it differently.

### Identifying the containing block of a node

- If the [position type](/docs/styling/position) of a node is static or relative then the containing block
  is always the _content box_ of the parent. This is because in Yoga every node is a
  flex container and therefore establishes a formatting context which would form a
  containing block on the web. The content box is formed by the node without margin, padding, or borders.
- If the [position type](/docs/styling/position) of a node is absolute then the containing block will be
  the _padding box_ (the content box plus padding) of any of:
  - The nearest non-static ancestor.
  - The nearest ancestor which is configured to always form a containing block. This
    is helpful for supporting things outside of Yoga which would form a containing block
    on the web, such as [filters](https://developer.mozilla.org/en-US/docs/Web/CSS/filter)
    or [transforms](https://developer.mozilla.org/en-US/docs/Web/CSS/transform). This
    is done by calling the corresponding API for the language you are working in.
    <Tabs groupId="language">
    <TabItem value="cpp" label="C/C++">
    ```cpp
    YGNodeSetAlwaysFormsContainingBlock(node, true /*alwaysFormsContainingBlock*/);
    ```
    </TabItem>
    <TabItem value="java" label="Java">
    ```java
    node.setAlwaysFormsContainingBlock(true /*alwaysFormsContainingBlock*/);
    ```
    </TabItem>
    <TabItem value="js" label="JavaScript">
    ```typescript
    node.setAlwaysFormsContainingBlock(true /*alwaysFormsContainingBlock*/);
    ```
    </TabItem>
    </Tabs>
  - The root if none of the above apply. Note that this is different from the web
    which has the notion of the _initial containing block_ that depends on the size
    of the viewport.
- If the node in question is the root then there is no containing block, but it will
  use the `availableWidth` and `availableHeight` that is passed in to the call to
  [`CalculateLayout`](/docs/getting-started/laying-out-a-tree).

### What the containing block affects

- Any percentage-based lengths will depend on the size of the containing block.
  Specifically the [height](/docs/styling/width-height), top, and bottom properties will use the height of the
  containing block. The [width](/docs/styling/width-height), left, right, [margin](/docs/styling/margin-padding-border),
  and [padding](/docs/styling/margin-padding-border) will use the width of the containing block.
- Any insets (left, right, top, bottom, etc.) applied to absolute nodes will be
  relative to the corresponding edge of the containing block.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10
    }}>
    <Node
      style={{
        height: 100,
        width: 100,
        position: 'static'
      }}>
      <Node
        style={{
          height: 25,
          width: '50%',
          bottom: 10,
          position: 'absolute'
        }}
      />
    </Node>
  </Node>
</Layout>`} />

---

### Advanced External Layout Systems (`website/docs/advanced/external-layout-systems.mdx`)

---
sidebar_position: 3
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Integrating with external layout systems

It is typical for applications to have content whose size may be dependent on factors not expressible inside of Yoga. This can often include text, or views which are rendered or laid out using a different system. Yoga allows leaf nodes to delegate to a different layout system via **Measure Functions**.

## Setting a measure function

A measure function (callback) is set on a node, to instruct Yoga to ask an external layout system for sizing of a given structure when it is time to measure the leaf node.

<Tabs groupId="language">

<TabItem value="cpp" label="C/C++">

Measure functions in the C/C++ APIs are represented as C function pointers and do not carry state. A Yoga node may be associated with an external structure by setting a **context** on the node. This is a `void*` tag, which may be read during callbacks.


```cpp
Widget widget{};

YGNodeSetContext(node, &widget);
YGNodeSetMeasureFunc(node, &measureWidget);
```

</TabItem>

<TabItem value="java" label="Java">

Measure functions are represented by the `YogaMeasureFunction` interface. This interface can be fulfilled by an explicit subclass, an anonymous inner class, or a lambda. Framework data may be associated with the underlying measure function, or a global measure function may be used, with data set on the underlying Yoga node.


```java
Widget widget = new Widget();

node.setData(widget);
node.setMeasureFunction(MEASURE_WIDGET);
```

</TabItem>

<TabItem value="js" label="JavaScript">

Measure functions are represented as an anonymous function, which may be bound to framework data.

```ts
const widget = new Widget();

node.setMeasureFunction((width, widthMode, height, heightMode) => {
 ...
});
```

</TabItem>
</Tabs>

## Responding with measurements

Yoga will call a node's measure function if the node does not otherwise have a definite dimension. This measure function is given the available space in each axis if constrained, with border and padding already subtracted.

:::warning

Yoga is not guaranteed to call a node's measure function if the node already has a definite dimension. Final content dimensions for a node should be read from the node's layout results, instead of caching measure function results.

:::

Each axis is passed a `MeasureMode` as a constraint:
1. `Exactly`: The measured length of the given axis is imposed to be the available length. This corresponds to [`stretch-fit`](https://www.w3.org/TR/css-sizing-3/#stretch-fit-size) sizing.
2. `Undefined`: The measured length in the given axis should be the maximum natural length of the content. This corresponds to [`max-content`](https://www.w3.org/TR/css-sizing-3/#max-content) sizing.
3. `AtMost`: The measured length in the given axis should be the minimum of the available space in the axis, and the natural content size. This corresponds to [`fit-content`](https://www.w3.org/TR/css-sizing-3/#fit-content-size) sizing.

## Invalidating measurements

Yoga must be notified if the content associated with a node changes in a way which may effect measurement.

<Tabs groupId="language">

<TabItem value="cpp" label="C/C++">

```cpp
YGNodeMarkDirty(node);
```

</TabItem>

<TabItem value="java" label="Java">


```java
node.dirty();
```

</TabItem>

<TabItem value="js" label="JavaScript">

```ts
node.markDirty();
```

</TabItem>
</Tabs>

---

### Advanced Incremental Layout (`website/docs/advanced/incremental-layout.mdx`)

---
sidebar_position: 1
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Incremental layout

Most real-world UIs are not static. Yoga trees may be laid out incrementally to avoid large work when only a small portion of the UI changes. Yoga will automatically mark a node and its ancestors as "dirty" if the node's style or children are changed. During the first layout, all nodes are considered dirty, and every node is visited. On subsequent layout, any nodes that are not dirty are skipped, so long as their parent constraints have not changed.

Yoga exposes whether the layout of a node or its children have changed via a `HasNewLayout` flag. This flag may be read when applying Yoga layout results to avoid traversing any subtrees where there are no updates.

<Tabs groupId="language">

<TabItem value="cpp" label="C/C++">

```cpp
void applyLayout(YGNodeRef node) {
  if (!YGNodeHasNewLayout(node)) {
    return;
  }

  // Reset the flag
  YGNodeSetHasNewLayout(node, false);

  // Do the real work
  ...

  for (size_t i = 0; i < YGNodeGetChildCount(node); i++) {
    applyLayout(YGNodeGetChild(node, i));
  }
}
```

</TabItem>

<TabItem value="java" label="Java">

```java
void applyLayout(YogaNode node) {
  if (!node.hasNewLayout()) {
    return;
  }

  // Reset the flag
  node.markLayoutSeen();

  // Do the real work
  ...

  for (int i = 0; i < node.getChildCount(); i++) {
    applyLayout(node.getChildAt(i));
  }
}
```

</TabItem>

<TabItem value="js" label="JavaScript">

```javascript
function applyLayout(node) {
  if (!node.hasNewLayout()) {
    return;
  }

  // Reset the flag
  node.markLayoutSeen();

  // Do the real work
  ...

  for (let i = 0; i < node.getChildCount(); i++) {
    applyLayout(node.getChildAt(i));
  }
}
```

</TabItem>
</Tabs>

In the below example, we start with an already laid out tree. The style of `F` is then modified, dirtying the node and its ancestors. After layout, the dirtied nodes, and any effected children, are marked as having new layout.

| Clean tree | Dirtied tree | Has new layout |
| - | - | - |
|  |  |  |

---

### Getting Started Configuring Yoga (`website/docs/getting-started/configuring-yoga.mdx`)

---
sidebar_position: 2
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Configuring Yoga

Yoga may be configured to use different behavior, using a **Yoga Config**. A config is attached to a specific Yoga Node, allowing different parts of the Yoga tree to behave differently during layout.

Most UI frameworks will apply a single uniform configuration. It is common in these cases to allocate a single Yoga Config which lasts the duration of the application. Other ownership structures are possible, which allow scenarios like laying out part of a tree with a different layout conformance than another part of the tree.

| Global | Per-node | Contextual |
| - | - | - |
|  |  |  |

<Tabs groupId="language">

<TabItem value="cpp" label="C/C++">

```cpp
#include <yoga/Yoga.h>

YGConfigRef config = YGConfigNew();
// Setup config...

YGNodeRef root = YGNodeNewWithConfig(config);
```

:::warning

Yoga configs are not freed automatically, and should be freed via `YGConfigFree(config)` when no longer needed.

:::

</TabItem>

<TabItem value="java" label="Java">

```java
import com.facebook.yoga.YogaConfigFactory;
import com.facebook.yoga.YogaNodeFactory;

YogaConfig config = YogaConfigFactory.create();
// Setup config...

YogaNode root = YogaNodeFactory.create(config);
```

</TabItem>

<TabItem value="js" label="JavaScript">

```ts
import Yoga from 'yoga-layout';

const config = Yoga.Config.create();
// Setup config...

const root = Yoga.Node.create(config);
```

:::warning

Yoga configs are not freed automatically, and should be freed via `config.free()` when no longer needed.

A future revision of JavaScript bindings for Yoga may move to garbage collection to remove this requirement.

:::

</TabItem>
</Tabs>

## Layout Conformance and Yoga Errata

Yoga has historically had several behaviors which are not standards compliant, and can lead to styles being laid out differently compared to a web browser. Fixing issues with Yoga's behavior may change the layout of existing applications written against Yoga's previous behaviors. Yoga can be configured with a set of **Errata** which control whether Yoga prefers standard compliance, or backwards compatibility. By default, Yoga will prefer standards compliance.

Errata may be configured granularity, as a set of bit flags, with several common presets available:
1. `None` (default): Prefer standards compliance. Breaking layout fixes are enabled when updating Yoga.
2. `Classic`: Operate as close as possible to Yoga 1.x.
3. `All`: Enable the errata in `Classic`, alongside `StretchFlexBasis`, mapping to `UseLegacyStretchBehaviour` in Yoga 1.x, which was not enabled by default.

<Tabs groupId="language">

<TabItem value="cpp" label="C/C++">

```cpp
#include <yoga/Yoga.h>

YGConfigRef config = YGConfigNew();
YGConfigSetErrata(config, YGErrataClassic);
```

</TabItem>

<TabItem value="java" label="Java">

```java
import com.facebook.yoga.YogaConfigFactory;
import com.facebook.yoga.YogaErrata;

YogaConfig config = YogaConfigFactory.create();
config.setErrata(YogaErrata.CLASSIC);
```

</TabItem>

<TabItem value="js" label="JavaScript">

```ts
import Yoga, {Errata} from 'yoga-layout';

const config = Yoga.Config.create();
config.setErrata(Errata.Classic);
```

</TabItem>
</Tabs>

## Point Scale Factor

Yoga represents positions on a floating-point grid of "points". This would normally lead to edges of a layout box ending up on a subpixel boundary when displayed by the underlying UI framework. This can create issues such as inconsistent rendering, or blurriness. To mitigate this, Yoga will by default round positions such that box edges are aligned to a physical "pixel grid".

Nodes may be configured with a `PointScaleFactor` to inform Yoga of the mapping between points to physical pixels (usually the "density" of the display). Pixel grid rounding may be disabled by setting `PointScaleFactor` to `0`.

| Before rounding | After rounding |
| - | - |
|  |  |

<Tabs groupId="language">

<TabItem value="cpp" label="C/C++">

```cpp
#include <yoga/Yoga.h>

YGConfigRef config = YGConfigNew();
YGConfigSetPointScaleFactor(config, 2.0f);
```

</TabItem>

<TabItem value="java" label="Java">

```java
import com.facebook.yoga.YogaConfigFactory;

YogaConfig config = YogaConfigFactory.create();
config.setPointScaleFactor(2.0f);
```

</TabItem>

<TabItem value="js" label="JavaScript">

```ts
import Yoga from 'yoga-layout';

const config = Yoga.Config.create();
config.setPointScaleFactor(2);
```

</TabItem>
</Tabs>

---

### Getting Started Laying Out A Tree (`website/docs/getting-started/laying-out-a-tree.mdx`)

---
sidebar_position: 1
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Laying out a Yoga tree

Each box in Yoga is represented as a **Yoga Node**. These nodes form a tree which is used to store both input styles, and output layout results.

## Building a Yoga tree

Yoga nodes may be created, styled, and linked together. See [Styling](../styling/) for a more comprehensive reference of how to style a Yoga Node.

<Tabs groupId="language">

<TabItem value="cpp" label="C/C++">

```cpp
#include <yoga/Yoga.h>

YGNodeRef root = YGNodeNew();
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetWidth(root, 100.0f);
YGNodeStyleSetHeight(root, 100.0f);

YGNodeRef child0 = YGNodeNew();
YGNodeStyleSetFlexGrow(child0, 1.0f);
YGNodeStyleSetMargin(child0, YGEdgeRight, 10.0f);
YGNodeInsertChild(root, child0, 0.0f);

YGNodeRef child1 = YGNodeNew();
YGNodeStyleSetFlexGrow(child1, 1.0f);
YGNodeInsertChild(root, child1, 1.0f);
```

:::warning

Yoga Nodes are not freed automatically and should be discarded when no longer needed. Individual nodes may be freed by calling `YGNodeFree(node)`, or an entire Yoga tree may be freed by calling `YGNodeFreeRecursive(node)`.

:::

</TabItem>

<TabItem value="java" label="Java">

```java
import com.facebook.yoga.YogaEdge;
import com.facebook.yoga.YogaFlexDirection;
import com.facebook.yoga.YogaNode;
import com.facebook.yoga.YogaNodeFactory;
import com.facebook.yoga.YogaPositionType;

YogaNode root = YogaNodeFactory.create();
root.setFlexDirection(YogaFlexDirection.ROW);
root.setWidth(100.0f);
root.setHeight(100.0f);

YogaNode child0 = YogaNodeFactory.create();
child0.setFlexGrow(1.0f);
child0.setMargin(YogaEdge.Right, 10.0f);
root.addChildAt(child0, 0.0f);

YogaNode child1 =  YogaNodeFactory.create();
child1.setFlexGrow(1.0f);
root.addChildAt(child1, 1.0f);
```

:::info

Java backed Yoga Nodes are garbage collected, and do not need to manually be freed.

:::

</TabItem>

<TabItem value="js" label="JavaScript">

```ts
import Yoga, {Direction, Edge, FlexDirection, PositionType} from 'yoga-layout';

const root = Yoga.Node.create();
root.setFlexDirection(FlexDirection.Row);
root.setWidth(100);
root.setHeight(100);

const child0 = Yoga.Node.create();
child0.setFlexGrow(1);
child0.setMargin(Edge.Right, 10);
root.insertChild(child0, 0);

const child1 = Yoga.Node.create();
child1.setFlexGrow(1);
root.insertChild(child1, 1);
```

:::warning

Yoga Nodes are not freed automatically and should be discarded when no longer needed. Individual nodes may be freed by calling `node.free()`, or an entire Yoga tree may be freed by calling `node.freeRecursive()`.

Nodes live in the WebAssembly heap, which is not visible to the JavaScript garbage collector. An application which repeatedly leaks nodes will grow the heap until new nodes fail to allocate. If an exception may be thrown after nodes are created (e.g. from within a [measure function](../advanced/external-layout-systems.mdx) during layout), freeing in a `finally` block guarantees the tree is released:

```ts
try {
  root.calculateLayout(undefined, undefined, Direction.LTR);
  // Read layout results, e.g. child0.getComputedLeft()
} finally {
  root.freeRecursive();
}
```

A future revision of JavaScript bindings for Yoga may move to garbage collection to remove this requirement.

:::

</TabItem>
</Tabs>

## Laying out the tree

The full tree of Yoga nodes is laid out all at once. This layout may be constrained to a passed `availableWidth` and `availableHeight`, or may be allowed to expand infinitely in a given axis by passing Undefined.

<Tabs groupId="language">

<TabItem value="cpp" label="C/C++">

```cpp
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
```

</TabItem>

<TabItem value="java" label="Java">

```java
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
```

:::info

A tree of Java Yoga nodes may be laid out in RTL by setting the `direction` of the root node.

:::

</TabItem>

<TabItem value="js" label="JavaScript">

```ts
root.calculateLayout(undefined, undefined, Direction.LTR);
```

</TabItem>
</Tabs>

## Reading layout results

Layout results are now written to each Yoga node. This includes an offset relative to the border box of the node's parent, along with dimensions, and the resolved values for margin, border, and padding for each physical edge.

<Tabs groupId="language">

<TabItem value="cpp" label="C/C++">

```cpp
float left = YGNodeLayoutGetLeft(child0);
float height = YGNodeLayoutGetHeight(child0);
```

</TabItem>

<TabItem value="java" label="Java">

```java
float left = child0.getLayoutX();
float height = child0.getLayoutHeight();
```

</TabItem>

<TabItem value="js" label="JavaScript">

```ts
const left = child0.getComputedLeft();
const height = child0.getComputedHeight();
```

</TabItem>
</Tabs>

---

### Styling Align Content (`website/docs/styling/align-content.mdx`)

---
sidebar_position: 1
---

import Playground from '@site/src/components/Playground';

# Align Content

Align content defines the distribution of lines along the cross-axis. This only
has effect when items are wrapped to multiple lines using [flex wrap](/docs/styling/flex-wrap).

**Flex start (default)**: Align wrapped lines to the start of the container's cross axis.

**Flex end**: Align wrapped lines to the end of the container's cross axis.

**Stretch**: Stretch wrapped lines to match the [height](/docs/styling/width-height) of the container's cross axis.

**Center**: Align wrapped lines in the center of the container's cross axis.

**Space between**: Evenly space wrapped lines across the container's cross axis, distributing
remaining space between the lines.

**Space around**: Evenly space wrapped lines across the container's cross axis, distributing
remaining space around the lines. Compared to space between using
space around will result in space being distributed to the beginning of
the first lines and end of the last line.

**Space evenly**: Evenly space wrapped lines across the container's cross axis, distributing
remaining space around the lines. Compared to space around, space evenly will not
double the gaps between children. The size of gaps between children and between
the parent's edges and the first/last child will all be equal.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 250,
      padding: 10,
      alignContent: 'flex-start',
      flexWrap: 'wrap',
    }}>
    <Node style={{margin: 5, height: 50, width: 50}} />
    <Node style={{margin: 5, height: 50, width: 50}} />
    <Node style={{margin: 5, height: 50, width: 50}} />
    <Node style={{margin: 5, height: 50, width: 50}} />
  </Node>
</Layout>`} />

---

### Styling Align Items Self (`website/docs/styling/align-items-self.mdx`)

---
sidebar_position: 2
---

import Playground from '@site/src/components/Playground';

# Align Items

Align items describes how to align children along the cross axis of their container.
Align items is very similar to [justify content](/docs/styling/justify-content) but instead of
applying to the main axis, align items applies to the cross axis.

**Stretch (default)**: Stretch children of a container to match the [height](/docs/styling/width-height) of the container's cross axis.

**Flex start**: Align children of a container to the start of the container's cross axis.

**Flex end**: Align children of a container to the end of the container's cross axis.

**Center**: Align children of a container in the center of the container's cross axis.

**Baseline**: Align children of a container along a common baseline. Individual children can be set to be the reference baseline for their parents.

# Align Self

Align self has the same options and effect as align items but instead of
affecting the children within a container, you can apply this property to
a single child to change its alignment within its parent. Align self
overrides any option set by the parent with align items.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 250,
      padding: 10,
      alignItems: 'flex-start',
    }}>
    <Node
      style={{
        margin: 5,
        height: 50,
        width: 50,
        alignSelf: 'center',
      }}
    />
    <Node style={{margin: 5, height: 50, width: 50}} />
  </Node>
</Layout>`} />

---

### Styling Aspect Ratio (`website/docs/styling/aspect-ratio.mdx`)

---
sidebar_position: 3
---

import Playground from '@site/src/components/Playground';

# Aspect Ratio

The aspect ratio property in Yoga has the following properties:

- Accepts any floating point value > 0, the default is undefined.
- Defined as the ratio between the [width](/docs/styling/width-height) and the [height](/docs/styling/width-height) of a node e.g. if a node has an aspect ratio of 2 then its [width](/docs/styling/width-height) is twice the size of its [height](/docs/styling/width-height).
- Respects the [min](/docs/styling/min-max-width-height) and [max](/docs/styling/min-max-width-height) dimensions of an item.
- Has higher priority than [flex grow](/docs/styling/flex-basis-grow-shrink)
- If aspect ratio, [width](/docs/styling/width-height), and [height](/docs/styling/width-height) are set then the cross axis dimension is overridden.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10,
    }}>
    <Node style={{margin: 5, height: 50, aspectRatio: 1.0}} />
    <Node style={{margin: 5, height: 50, aspectRatio: 1.5}} />
  </Node>
</Layout>`} />

---

### Styling Display (`website/docs/styling/display.mdx`)

---
sidebar_position: 4
---

import Playground from '@site/src/components/Playground';

# Display

Display controls which layout specification to follow.

**Flex (default)**: The CSS Flexible Box Model specification.

**None**: The node is removed from the layout tree and will not be visible.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10,
    }}>
    <Node style={{margin: 5, height: 50, display: 'none'}} />
    <Node style={{margin: 5, height: 50, display: 'flex'}} />
  </Node>
</Layout>`} />

---

### Styling Flex Basis Grow Shrink (`website/docs/styling/flex-basis-grow-shrink.mdx`)

---
sidebar_position: 5
---

import Playground from '@site/src/components/Playground';

# Flex Basis, Grow, and Shrink

**Flex basis**: Is an axis-independent way of providing the default size of an item
along the main axis. Setting the flex basis of a child is similar to setting the [width](/docs/styling/width-height) of that
child if its parent is a container with a row [flex direction](/docs/styling/flex-direction) or setting the [height](/docs/styling/width-height) of a child
if its parent is a container with a column [flex direction](/docs/styling/flex-direction). The flex basis of an item is the
default size of that item, the size of the item before any flex grow and flex shrink
calculations are performed.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10,
    }}>
    <Node style={{margin: 5, flexBasis: 50}} />
  </Node>
</Layout>`} />

**Flex grow**: Describes how any space within a container should be distributed
among its children along the main axis. After laying out its children, a container will
distribute any remaining space according to the flex grow values specified by its children.

Flex grow accepts any floating point value >= 0, with 0 being the default value.
A container will distribute any remaining space among its children weighted by the child’s flex grow value.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10,
    }}>
    <Node style={{margin: 5, flexGrow: 0.25}} />
    <Node style={{margin: 5, flexGrow: 0.75}} />
  </Node>
</Layout>`} />

**Flex shrink**: Describes how to shrink children along the main axis in the
case that the total size of the children overflow the size of the container on the main axis.
flex shrink is very similar to flex grow and can be thought of in the same way if
any overflowing size is considered to be negative remaining space.
These two properties also work well together by allowing children to grow and shrink as needed.

Flex shrink accepts any floating point value >= 0, with 1 being the default value.
A container will shrink its children weighted by the child’s flex shrink value.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10,
    }}>
    <Node style={{margin: 5, flexShrink: 5, height: 150}} />
    <Node style={{margin: 5, flexShrink: 10, height: 150}} />
  </Node>
</Layout>`} />

---

### Styling Flex Direction (`website/docs/styling/flex-direction.mdx`)

---
sidebar_position: 6
---

import Playground from '@site/src/components/Playground';

# Flex Direction

Flex direction controls the direction in which children of a node are laid out.
This is also referred to as the main axis. The main axis is the direction in
which children are laid out. The cross axis is the axis perpendicular to the
main axis, or the axis which wrapping lines are laid out in.

**Column (default)**: Align children from top to bottom. If [wrapping](/docs/styling/flex-wrap) is enabled then
the next line will start to the left first item on the top of the container.

**Row**: Align children from left to right. If [wrapping](/docs/styling/flex-wrap) is enabled then
the next line will start under the first item on the left of the container.

**Row reverse**: Align children from right to left. If [wrapping](/docs/styling/flex-wrap) is enabled then
the next line will start under the first item on the right of the container.

**Column reverse**: Align children from bottom to top. If [wrapping](/docs/styling/flex-wrap) is enabled then
the next line will start to the left first item on the bottom of the container.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10,
      flexDirection: 'column',
    }}>
    <Node style={{margin: 5, height: 50, width: 50}} />
    <Node style={{margin: 5, height: 50, width: 50}} />
  </Node>
</Layout>`} />

---

### Styling Flex Wrap (`website/docs/styling/flex-wrap.mdx`)

---
sidebar_position: 7
---

import Playground from '@site/src/components/Playground';

# Flex Wrap

The flex wrap property is set on containers and controls what happens when
children overflow the size of the container along the main axis. By default
children are forced into a single line (which can shrink nodes). When wrapping lines [align content](/docs/styling/align-content) can be used to specify how the
lines are placed in the container.

**No wrap (default)**: No wrapping and children might shrink as a result.

**Wrap**: Nodes are wrapped into multiple lines along the main axis if needed.

**Wrap reverse**: Behaves the same as wrap but the order of the lines is reversed.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 250,
      padding: 10,
      flexWrap: 'wrap',
    }}>
    <Node style={{margin: 5, height: 50, width: 50}} />
    <Node style={{margin: 5, height: 50, width: 50}} />
    <Node style={{margin: 5, height: 50, width: 50}} />
    <Node style={{margin: 5, height: 50, width: 50}} />
  </Node>
</Layout>`} />

---

### Styling Gap (`website/docs/styling/gap.mdx`)

---
sidebar_position: 8
---
import Playground from '@site/src/components/Playground';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Gap

Gap will add spacing between the rows and columns of a flex container. You can
specify if you want the gaps to be between only the rows, only the columns, or
both. You can do this by passing in the corresponding gutter value to the API,
for example

<Tabs groupId="language">
<TabItem value="cpp" label="C/C++">
```cpp
YGNodeStyleSetGap(node, YGGutterRow, amount);
```
</TabItem>
<TabItem value="java" label="Java">
```java
node.setGap(YogaGutter.ROW, amount);
```
</TabItem>
<TabItem value="js" label="JavaScript">
```typescript
node.setGap(Gutter.Row, amount);
```
</TabItem>
</Tabs>


<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 250,
      padding: 10,
      flexWrap: 'wrap',
      gap: 10,
    }}>
    <Node style={{height: 50, width: 50}} />
    <Node style={{height: 50, width: 50}} />
    <Node style={{height: 50, width: 50}} />
    <Node style={{height: 50, width: 50}} />
    <Node style={{height: 50, width: 50}} />
  </Node>
</Layout>`} />

---

### Styling Insets (`website/docs/styling/insets.mdx`)

---
sidebar_position: 8.5
---

import Playground from '@site/src/components/Playground';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Insets

Insets refer to the position property that you can assign to an edge
(not to be confused with [position type](/docs/styling/position)) using one of the following
APIs:
<Tabs groupId="language">
<TabItem value="cpp" label="C/C++">
```cpp
YGNodeStyleSetPosition(node, edge, position);
```
</TabItem>
<TabItem value="java" label="Java">
```java
node.setPosition(edge, position);
```
</TabItem>
<TabItem value="js" label="JavaScript">
```typescript
node.setPosition(edge, position);
```
</TabItem>
</Tabs>
This property will offset the node in a specific way depending on
what [position type](/docs/styling/position) the node has.

* If the node is static then insets have no effect.
* If the node is relative then insets will move the node the designated amount
from where the node would normally be in the container. Each inset property
is relative to the node's corresponding physical edge. So `YGNodeStyleSetPosition(node, YGEdgeRight, 10.0f)` will offset the node
so that the right edge is 10 units away from where the right edge would be originally.
* If the node is absolute then insets will move the node the designated amount away from
the node's [containing block](/docs/advanced/containing-block). So `YGNodeStyleSetPosition(node, YGEdgeRight, 10.0f)`
will offset the node so that the right edge is 10 units away from the [containing block's](/docs/advanced/containing-block)
right edge.

In the event that a node has a fixed size and opposite insets are defined
(e.g. a value assigned to the right edge and left edge) then the left and top edge will have priority.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
    }}>
    <Node
      style={{
        height: 50,
        width: 50,
        top: 50,
        left: 50,
      }}
    />
  </Node>
</Layout>`} />

---

### Styling Justify Content (`website/docs/styling/justify-content.mdx`)

---
sidebar_position: 9
---

import Playground from '@site/src/components/Playground';

# Justify Content

Justify content describes how to align children within the main axis of their container.
For example, you can use this property to center a child horizontally within a container
with [flex direction](/docs/styling/flex-direction) set to row or vertically within a container with [flex direction](/docs/styling/flex-direction)
set to column.

**Flex start (default)**: Align children of a container to the start of the container's main axis.

**Flex end**: Align children of a container to the end of the container's main axis.

**Center**: Align children of a container in the center of the container's main axis.

**Space between**: Evenly space of children across the container's main axis, distributing
remaining space between the children.

**Space around**: Evenly space of children across the container's main axis, distributing
remaining space around the children. Compared to space between using
space around will result in space being distributed to the beginning of
the first child and end of the last child.

**Space evenly**: Evenly distributed within the alignment container along the main axis.
The spacing between each pair of adjacent items, the main-start edge and the first item,
and the main-end edge and the last item, are all exactly the same.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10,
      justifyContent: 'flex-start',
    }}>
    <Node style={{margin: 5, height: 50, width: 50}} />
    <Node style={{margin: 5, height: 50, width: 50}} />
  </Node>
</Layout>`} />

---

### Styling Layout Direction (`website/docs/styling/layout-direction.mdx`)

---
sidebar_position: 10
---

import Playground from '@site/src/components/Playground';

# Layout Direction

Layout direction specifies the direction in which children and text
in a hierarchy should be laid out. Layout direction also effects what
edge `start` and `end` refer to. By default Yoga lays out with left-to-right (LTR)
layout direction. In this mode `start` refers to `left` and `end`
refers to `right`. When localizing your apps for markets with right-to-left (RTL) languages
you should customize this by either by passing a direction
to the [CalculateLayout](/docs/getting-started/laying-out-a-tree) call or by setting the direction on the root node.

**LTR (default)**: Text and children and laid out from left to right. Styles applied
the start of an element are applied on the left side.

**RTL**: Text and children and laid out from right to left. Styles applied the
start of an element are applied on the right side.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10,
      direction: 'ltr',
    }}>
    <Node style={{margin: 5, height: 50, width: 50}} />
    <Node style={{margin: 5, height: 50, width: 50}} />
  </Node>
</Layout>`} />

---

### Styling Margin Padding Border (`website/docs/styling/margin-padding-border.mdx`)

---
sidebar_position: 11
---

import Playground from '@site/src/components/Playground';

# Margin, Padding, and Border

**Margin**: Affects the spacing around the outside of a node. A node with margin
will offset itself from the bounds of its parent but also offset the
location of any siblings. The margin of a node contributes to the total size
of its parent if the parent is auto sized.

**Padding**: Affects the size of the node it is applied to. Padding in Yoga acts as if
`box-sizing: border-box;` was set. That is padding will not add to the total size
of an element if it has an explicit size set. For auto sized nodes padding will increase
the size of the node as well as offset the location of any children.

**Border**: in Yoga acts exactly like padding and only exists as a separate property so
that higher level frameworks get a hint as to how thick to draw a border. Yoga however
does not do any drawing so just uses this information during layout where border
acts exactly like padding.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10,
    }}>
    <Node
      style={{
        margin: 5,
        padding: 20,
        borderWidth: 20,
        height: 50,
      }}
    />
    <Node style={{height: 50}} />
  </Node>
</Layout>`} />

---

### Styling Min Max Width Height (`website/docs/styling/min-max-width-height.mdx`)

---
sidebar_position: 12
---

import Playground from '@site/src/components/Playground';

# Min/Max Width and Height

These properties set the maximum and minimum size constraints of a node.
They have higher priority than all other properties and will always be respected.
Constraints can be specified as either absolute pixel values or as percentages of their
[containing block's](/docs/advanced/containing-block) size. By default all these constraints are `undefined`.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 250,
      padding: 10,
    }}>
    <Node style={{margin: 5, height: 25}} />
    <Node
      style={{
        margin: 5,
        height: 100,
        maxHeight: 25,
      }}
    />
    <Node
      style={{
        margin: 5,
        height: 25,
        minHeight: 50,
      }}
    />
    <Node
      style={{
        margin: 5,
        height: 25,
        maxWidth: 25,
      }}
    />
    <Node
      style={{
        margin: 5,
        height: 25,
        width: 25,
        minWidth: 50,
      }}
    />
  </Node>
</Layout>`} />

---

### Styling Position (`website/docs/styling/position.mdx`)

---
sidebar_position: 11
---

import Playground from '@site/src/components/Playground';

# Position

**Relative (default)**: This node is laid out according to the specified flow of the flex container it is a part of.
That is, it participates in the flexbox algorithm and will take up space within the container, unlike absolute.
[Insets](/docs/styling/insets) will offset the node from its normal position within its container.
This node will always form a [containing block](/docs/advanced/containing-block).

**Absolute**: This node is removed from the specified flow of the flex container it is a part of.
Absolute nodes do not take up space in its flex container and will not affect the position of
its siblings. [Insets](/docs/styling/insets) will offset the node from its [containing block](/docs/advanced/containing-block).

**Static**: This node behaves like relative except it will ignore [insets](/docs/styling/insets) and will not
form a [containing block](/docs/advanced/containing-block).

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10,
    }}>
    <Node
      style={{
        margin: 5,
        height: 50,
        top: 20,
        position: 'relative',
      }}
    />
  </Node>
</Layout>`} />

---

### Styling Width Height (`website/docs/styling/width-height.mdx`)

---
sidebar_position: 14
---

import Playground from '@site/src/components/Playground';

# Width and Height

The width property specifies the width of the node's border box (the collective size of the node's content, padding, and border).
Similarly height property specifies the height of the node's border box.

Both width and height can take following values:

**Auto**: The default Value, Yoga calculates the width/height for the node based
on its content, whether that is other children, text, or an image.

**Pixels**: Defines the width/height in absolute pixels. Depending on other properties set on
the Yoga node this may or may not be the final dimension of the node.

**Percentage**: Defines the width or height in percentage of its [containing block's](/docs/advanced/containing-block) width or height respectively.

<Playground code={`<Layout config={{useWebDefaults: false}}>
  <Node
    style={{
      width: 200,
      height: 200,
      padding: 10,
    }}>
    <Node
      style={{
        margin: 5,
        height: 50,
        width: 50,
      }}
    />
  </Node>
</Layout>`} />

---

--- METRICS ---
- Files Extracted: 25
- Estimated Token Budget: ~11874 tokens
- Canonical Reference: https://codewiki.google/github.com/react/yoga
