Layout¶
Rezi uses a cell-based layout system: all sizes and coordinates are measured in terminal character cells (not pixels). This makes layout deterministic across platforms and terminal emulators.
This page covers the core layout primitives and the props that control sizing and positioning.
Cell coordinates¶
Every widget is laid out into a rectangle:
x,y— top-left corner in cells (0,0 is the top-left of the terminal)w,h— width/height in cells
(0,0) ───────────────────────────► x
│
│ ┌────────────── w ──────────────┐
│ │ │
▼ │ h │
y │ │
└────────────────────────────────┘
Stack layouts¶
The primary layout containers are stacks:
ui.row(props, children)— horizontal stackingui.column(props, children)— vertical stacking
Key props:
gap— spacing between children (cells or spacing key)align— cross-axis alignment:"start" | "center" | "end" | "stretch"justify— main-axis distribution:"start" | "end" | "center" | "between" | "around" | "evenly"
Example: Row + Column¶
import { createApp, ui } from "@rezi-ui/core";
import { createNodeBackend } from "@rezi-ui/node";
const app = createApp({
backend: createNodeBackend(),
initialState: {},
});
app.view(() =>
ui.column({ p: 1, gap: 1 }, [
ui.text("Header"),
ui.row({ gap: 2, justify: "between" }, [
ui.text("Left"),
ui.text("Right"),
]),
])
);
await app.start();
Padding and margins¶
Container widgets accept spacing props (values are cells, or named keys like "sm", "md", "lg"):
Padding (inside)¶
p(all),px/py,pt/pr/pb/pl
Margin (outside)¶
m(all),mx/my
Example:
import { ui } from "@rezi-ui/core";
ui.box({ p: "md", mx: "lg", border: "rounded", title: "Panel" }, [
ui.text("Content"),
]);
Notes:
- Padding reduces the available content area for children.
- Margin affects how the widget is positioned inside its parent stack.
Alignment¶
Alignment depends on the stack direction:
- In a
row,aligncontrols vertical alignment;justifycontrols horizontal distribution. - In a
column,aligncontrols horizontal alignment;justifycontrols vertical distribution.
Example:
import { ui } from "@rezi-ui/core";
ui.row({ height: 3, align: "center", justify: "between" }, [
ui.text("A"),
ui.text("B"),
]);
Size constraints¶
Most container widgets accept layout constraints:
width/height: number of cells, percentage string ("50%"), or"auto"minWidth/maxWidth,minHeight/maxHeightflex: main-axis space distribution insiderow/columnaspectRatio: enforcew/h
Example: fixed + flex children in a row
import { ui } from "@rezi-ui/core";
ui.row({ gap: 1 }, [
ui.box({ width: 20, border: "single" }, [ui.text("Fixed 20")]),
ui.box({ flex: 1, border: "single" }, [ui.text("Flex fill")]),
]);
Borders¶
ui.box can draw a border around its content:
border:"none" | "single" | "double" | "rounded" | "heavy" | "dashed" | "heavy-dashed"title: optional title rendered in the top bordertitleAlign:"left" | "center" | "right"
Border thickness is 1 cell on each edge (unless border: "none"). Padding is applied inside the border.
Example:
import { ui } from "@rezi-ui/core";
ui.box({ title: "Settings", titleAlign: "center", border: "double", p: 1 }, [
ui.text("Option A"),
ui.text("Option B"),
]);
Nested layouts¶
Nesting is just composition: put stacks/boxes inside stacks/boxes.
Example: sidebar + content column
import { ui } from "@rezi-ui/core";
ui.row({ gap: 1 }, [
ui.box({ width: 24, border: "rounded", p: 1, title: "Sidebar" }, [
ui.column({ gap: 1 }, [ui.text("One"), ui.text("Two")]),
]),
ui.box({ flex: 1, border: "rounded", p: 1, title: "Content" }, [
ui.text("Main area"),
]),
]);
Overflow¶
Rezi clips rendering to each widget’s allocated rect. Overflow is handled per-widget:
ui.textsupportstextOverflow: "clip" | "ellipsis"(andmaxWidth)- Containers clip their children to the padded/bordered content area
Example: ellipsis truncation
import { ui } from "@rezi-ui/core";
ui.box({ width: 20, border: "single", p: 1 }, [
ui.text("This is a long line that will truncate", { textOverflow: "ellipsis" }),
]);
Related¶
- Concepts - How VNodes and reconciliation work
- Lifecycle & Updates - When layout runs and why updates are committed
- Styling - Background fills, borders, and style inheritance
Next: Input & focus.