# Layout and the Relative model

> How CrossFly measures and positions — relative by default — and why this is the basis of responsiveness.

Source: https://crossfly.dev/docs/concepts/the-layout-and-relative-model — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Layout and the Relative model

CrossFly is **relative by default, not absolute**. Understanding this explains why your screens adapt
on their own to different sizes, densities, and rotations.

## The layout contract
Each container delegates the arrangement of its children to a `Layout`. The cycle, cascading, is always:

**measure → position → propagate `onLayout` to the children.**

When the layout is invalidated (size, content, or rotation changed), the framework redoes this cycle
from the root. You don't recompute positions by hand — you declare the **intent** and the `Layout` resolves it.

## The spectrum of layouts (by intent)
- **Stack** (vertical/horizontal) → `VerticalLayout` / `HorizontalLayout`
- **Fractional grid** → `GridLayout`
- **Anchor one component to another** → `RelativeLayout`
- **Space evenly** → `EvenlySpacedLayout`
- **Free position** → `RandomLayout`

Swapping a container's `Layout` changes the arrangement without touching the children — this is what makes responding to
rotation trivial. (How-to in [Layouts](/docs/ui/layouts).)

## The conceptual heart: `Relative`
Sizes and positions are not fixed pixels — they are **relationships**. The four forms:

| Form | Meaning | Scales with |
|---|---|---|
| `Relative.ofFont(1.5f)` | fraction of the **font height** | the UI zoom/density |
| `Relative.ofScreen(0.8f[, ScreenSize])` | fraction of the **screen** | the screen size / orientation |
| `LAY_FILL` / `LAY_AUTO` / fraction | fraction of the **container** | the parent's size |
| `Relative.ofPixels(24f)` | **absolute pixel** | nothing (use by exception) |

And the `Gap` (`ingap` padding / `outgap` margin) follows the same logic: `Gap.ofFont(...)` scales along.

```java
// header (content height), content (absorbs the slack), footer (content) — in a VerticalLayout:
tela.add(LAY_AUTO, header);
tela.add(LAY_FILL, conteudo);   // the "elastic" one
tela.add(LAY_AUTO, footer);
```

## Why this is the basis of responsiveness
If **there are no fixed pixels scattered around**, the framework can **recompute everything** on each resize, rotation, or
scale change — and the screen simply readapts. Responsiveness is not a separate feature: it is a
consequence of measuring by relationships.

> Rule of thumb: write sizes as `Relative`/fractions/`LAY_FILL`; reserve `ofPixels` for genuinely
> fixed cases. A fixed pixel is a bet that the screen never changes — and it always changes.

## See also
- Apply: [Layouts](/docs/ui/layouts) · [Responsiveness](/docs/ui/layouts/responsiveness)
- Next: [Styles and themes](/docs/concepts/styling-and-theming-model)
