Constraints
Constraints declaratively control element positioning. Add them to the constraints array in a scene document or via the addConstraint operation.
Building an agent integration? See How AI Agents Should Use Zindex for the recommended workflow for scene creation, incremental edits, revision handling, validation, normalization, and rendering.
Each constraint has a type, a unique id, and type-specific parameters.
align
Align elements along a single axis by their centers.
{
"id": "c1",
"type": "align",
"axis": "y",
"elements": ["btn1", "btn2", "btn3"]
}
| Parameter | Required | Description |
|---|---|---|
axis | Yes | "x" or "y" - axis to align on |
elements | Yes | Element IDs to align |
Elements are moved so their centers share the same coordinate on the specified axis.
distribute
Space elements evenly along an axis.
{
"id": "c2",
"type": "distribute",
"axis": "x",
"elements": ["icon1", "icon2", "icon3", "icon4"],
"gap": 20
}
| Parameter | Required | Description |
|---|---|---|
axis | Yes | "x" or "y" - distribution direction |
elements | Yes | Element IDs to distribute |
gap | No | Pixel spacing between elements (default: 0) |
First element stays in place. Subsequent elements are spaced evenly.
stack
Stack elements sequentially along one axis.
{
"id": "c3",
"type": "stack",
"axis": "y",
"elements": ["title", "description", "button"],
"gap": 8
}
| Parameter | Required | Description |
|---|---|---|
axis | Yes | "x" or "y" - stacking direction |
elements | Yes | Element IDs to stack |
gap | No | Pixel spacing between elements (default: 0) |
First element stays in place. Each subsequent element is positioned directly after the previous one.
grid
Arrange elements in a grid layout.
{
"id": "c4",
"type": "grid",
"elements": ["a", "b", "c", "d", "e", "f"],
"columns": 3,
"columnGap": 16,
"rowGap": 16
}
| Parameter | Required | Description |
|---|---|---|
elements | Yes | Element IDs to arrange |
columns | No | Number of columns (default: 2) |
rows | No | Number of rows (optional) |
columnGap | No | Horizontal spacing (default: 0) |
rowGap | No | Vertical spacing (default: 0) |
Elements are laid out left-to-right, top-to-bottom. The first element’s position is the grid origin.
sameSize
Make elements the same dimensions.
{
"id": "c5",
"type": "sameSize",
"elements": ["btn1", "btn2", "btn3"],
"dimension": "width"
}
| Parameter | Required | Description |
|---|---|---|
elements | Yes | Element IDs to resize |
dimension | No | "width", "height", or "both" (default: "both") |
The first element’s size is used as the reference.
contain
Expand a container to fit its child elements with padding.
{
"id": "c6",
"type": "contain",
"containerId": "group1",
"elements": ["node1", "node2", "node3"],
"padding": 20
}
| Parameter | Required | Description |
|---|---|---|
containerId | Yes | Container element ID to resize |
elements | Yes | Child element IDs that must fit inside |
padding | No | Pixel padding around children (default: 0) |
The container is resized to the bounding box of all children, plus padding.
centerIn
Center elements inside a container.
{
"id": "c7",
"type": "centerIn",
"containerId": "header",
"elements": ["logo"],
"axis": "both"
}
| Parameter | Required | Description |
|---|---|---|
containerId | Yes | Container element ID |
elements | Yes | Element IDs to center |
axis | No | "x", "y", or "both" (default: "both") |
minGap
Enforce minimum spacing between elements.
{
"id": "c8",
"type": "minGap",
"axis": "y",
"elements": ["item1", "item2", "item3"],
"gap": 8
}
| Parameter | Required | Description |
|---|---|---|
axis | Yes | "x" or "y" - spacing direction |
elements | Yes | Element IDs to check |
gap | Yes | Minimum pixel gap required |
Elements that are closer than the minimum gap are pushed apart.
noOverlap
Prevent elements from overlapping.
{
"id": "c9",
"type": "noOverlap",
"elements": ["label1", "label2", "label3"]
}
| Parameter | Required | Description |
|---|---|---|
elements | Yes | Element IDs to check |
Overlapping elements are shifted apart horizontally.
order
Hard ordering constraint enforced during auto-layout. Controls which rank (layer) a node lands on and its position within a rank.
{
"id": "c10",
"type": "order",
"source": "db",
"target": "api",
"relation": "rightOf"
}
| Parameter | Required | Description |
|---|---|---|
source | Yes | Element ID of the source node |
target | Yes | Element ID of the target node |
relation | Yes | "leftOf" | "rightOf" | "above" | "below" | "sameRank" |
The relation describes the source relative to the target. For example, { source: "db", target: "api", relation: "rightOf" } places the database to the right of the API.
above and below control rank assignment (which layer a node lands in). leftOf and rightOf control position within the same rank. sameRank forces two nodes into the same layer.
Only applies to auto-laid-out nodes. Nodes with explicit layout positions are unaffected. Conflicting constraints (cycles) are detected and gracefully dropped rather than crashing the layout.
Adding constraints via operations
Use the addConstraint operation to add constraints to an existing scene:
{
"op": "addConstraint",
"constraint": {
"id": "c1",
"type": "align",
"axis": "y",
"elements": ["api", "db", "cache"]
}
}
Use removeConstraint to remove:
{
"op": "removeConstraint",
"id": "c1"
}