Skip to content

GridBox

GridBox (from scenerystack/scenery) is a Node that arranges its children in a two-dimensional grid of rows and columns, similar to CSS grid. Where FlowBox only handles one axis at a time, GridBox positions each child at an explicit (row, column) cell (or lets it auto-place), independently controlling per-column width and per-row height so everything lines up.

ts
import { GridBox, Rectangle, Circle } from 'scenerystack/scenery';

const grid = new GridBox( {
  xSpacing: 10,
  ySpacing: 8,
  children: [
    new Rectangle( 0, 0, 40, 40, { fill: 'teal', layoutOptions: { column: 0, row: 0 } } ),
    new Circle( 20, { fill: 'crimson', layoutOptions: { column: 1, row: 0 } } ),
    new Rectangle( 0, 0, 90, 20, { fill: 'goldenrod', layoutOptions: { column: 0, row: 1, horizontalSpan: 2 } } )
  ]
} );

Each child's cell position and span are set through that child's layoutOptions, not through GridBox options — GridBox itself only configures grid-wide defaults (spacing, alignment, margins) and how auto-placement behaves.

GridBox-level options

OptionDefaultEffect
rowsSets children all at once from a 2D (Node | null)[][] (rows[row][column]); mutually exclusive with children/columns
columnsSame idea, transposed (columns[column][row]); mutually exclusive with children/rows
autoRowsnullWhen set, children auto-place into 1-column-wide cells, wrapping to a new column after this many rows
autoColumnsnullSame idea, wrapping to a new row after this many columns
resizetrueWhether the GridBox keeps re-running layout after construction
spacing0Shorthand for setting both xSpacing and ySpacing
xSpacing / ySpacing0Gap between columns / between rows
xAlign'center'Horizontal alignment within a cell: 'left', 'right', 'center', or 'origin'
yAlign'center'Vertical alignment within a cell: 'top', 'bottom', 'center', or 'origin'
margin / xMargin / yMargin / leftMargin / rightMargin / topMargin / bottomMargin0Per-cell margins, box-wide or overridable per child
minContentWidth / minContentHeight / maxContentWidth / maxContentHeightClamp the GridBox's own content size

Per-child layoutOptions (grid position)

These can only be set via a child's layoutOptions, not as GridBox constructor options:

layoutOptions keyEffect
columnZero-based column index for this child (leftmost column is 0)
rowZero-based row index for this child (topmost row is 0)
horizontalSpanNumber of columns this child occupies (default 1)
verticalSpanNumber of rows this child occupies (default 1)
xAlign / yAlign / xStretch / yStretch / xGrow / yGrow / marginsPer-child overrides of the corresponding GridBox-level option

Methods

MethodEffect
setLines( orientation, lineArrays ) / getLines( orientation )Programmatic equivalent of the rows/columns options, for reading or rewriting the whole grid at once
dispose()Releases layout listeners

Auto-placement vs. explicit placement

Use autoRows/autoColumns when children are added dynamically and you just want them to flow into a grid (like a tag list). Use explicit layoutOptions.row/.column (or the rows/columns constructor options) when the grid has a fixed, meaningful structure — the two approaches are mutually exclusive per the source's own NOTEs.

rows/columns rewrites layoutOptions and replaces all children

Passing rows or columns mutates every listed child's layoutOptions to bake in its (row, column) position, and replaces the GridBox's entire children list. Don't mix it with manually calling addChild()/removeChild() afterward without accounting for that; prefer autoRows/autoColumns or manual layoutOptions if you need to add/remove children incrementally.