Skip to main content

Containers & Layouts

Learn how to group elements and manage layouts automatically using Box, Stack, and Grid containers.


What are Containers?

Containers are special parent nodes that hold child nodes inside them. By placing nodes inside a container, they are grouped structurally.

Containers automatically manage the positions of their children based on their layout mode. Spayse features three container types:

Box (bare node)

Free-form container. Children are placed at explicit coordinates relative to the box. Just use a quoted label with { } children.

Stack (`stack`)

Flex-based container. Automatically arranges children in a single horizontal or vertical line.

Grid (`grid`)

Grid-based container. Arranges children into rows and columns.

1. Box Container (bare node)

A quoted label with { } children becomes a free-form box container. It does not automatically arrange its children; you position them manually using coordinates:

dsl
1234"Group Label" [color: blue] {  "Node A" [color: green]  "Node B" [color: green]}

2. Stack Container (`stack`)

A stack automatically arranges its children in a column (default) or a row. Use the direction: h attribute for horizontal layout. You do not need to specify coordinates for children inside a stack.

dsl
12345stack "Services" [direction: h] {  "Auth API" [process, color: blue]  "Users API" [process, color: blue]  "Billing API" [process, color: blue]}

Stack Layout Arguments

AttributeTypeDefaultDescription
direction"h" | "v""v"Stacking direction: horizontal ("h") or vertical ("v").
gapnumber12Space between elements in pixels.
paddingnumber12Internal padding of the container.
align"start" | "center" | "end" | "stretch""center"Alignment of children perpendicular to direction.
sizing"auto" | "fixed""auto"Sizing mode: fit-content ("auto") or fixed.
Loading preview...
A horizontal stack arranging three child nodes with consistent gaps

3. Grid Container (`grid`)

A grid organizes elements into rows and columns. Specify columns in the attribute block. The compiler calculates the number of rows automatically based on the number of children.

dsl
1234567grid "Cluster" [color: green] {  "Worker 1" [process, color: green]  "Worker 2" [process, color: green]  "Worker 3" [process, color: green]  "Worker 4" [process, color: green]  "Worker 5" [process, color: green]}

Grid Layout Arguments

AttributeTypeDefaultDescription
columnsnumber2Number of grid columns.
rowsnumbercalculatedNumber of grid rows. If omitted, calculated automatically as ceil(children / columns).
colGapnumber12Horizontal spacing between cells.
rowGapnumber12Vertical spacing between cells.
paddingnumber12Internal padding of the container.
cellSizing"fit-content" | "fit" | "fill" | "fixed""fit-content"Cell sizing mode.
alignItems"start" | "center" | "end" | "stretch""center"Cell alignment.

Grid Overflow & Safety

If you specify both `columns` and `rows`, but declare more children than `columns * rows`, the compiler will **not** drop your elements. Instead, it will automatically expand the number of rows to fit all children, and emit a warning diagnostic (`LAYOUT_AUTO_EXPANDED`).
Loading preview...
A 3-column grid container holding 5 workers, auto-calculating to 2 rows

Nesting Containers

You can nest containers inside each other to build highly structured layouts. For example, you can place a horizontal stack of databases inside a vertical stack of application tiers:

dsl
12345678stack "App Tier" [direction: v] {  "Load Balancer" [icon: server, color: blue]    stack "Database Tier" [direction: h] {    "Primary DB" [db, color: orange]    "Replica DB" [db, color: orange]  }}

Groups vs. Containers

In addition to layout containers, Spayscript supports the group statement. A group binds elements together on the canvas so you can select and move them as a single unit, but it **does not** enforce any layout rules or restrict coordinate spacing:

dsl
12345"Node A" [color: blue]"Node B" [color: green] // Group elements together without layout constraintsgroup "My Group" { "Node A", "Node B" }

Use a Group when you want to place elements in custom, free-form positions but want the convenience of moving them together. Use a Container (like a bare node, Stack, or Grid) when you want the Spayscript layout engine to automatically calculate positions, spacing, and parent-child hierarchies.