Alignment
Alignment controls where children sit within a container when there’s leftover space. It works on both axes — main and cross — and supports per-child overrides.
Main vs cross axis
Every Row/Column has two axes:
| Container | Main axis | Cross axis |
|---|---|---|
| Row | Horizontal | Vertical |
| Column | Vertical | Horizontal |
MainAlign controls position along the main axis (the direction children flow). CrossAlign controls position along the perpendicular axis.
MainAlign
Where the block of children sits on the main axis. Options: Start, Center, End.
AutoUI.Create() .Row().WidthFill().Height(60) .MainAlign(Alignment.Center) // children clustered horizontally in the middle .Children( AutoUI.Create().Width(80).Height(40), AutoUI.Create().Width(80).Height(40), AutoUI.Create().Width(80).Height(40) ) .Build();| Value | Effect |
|---|---|
Start | Children pinned to the start of the main axis (left for Row, top for Column) |
Center | Children clustered in the middle |
End | Children pinned to the end |
Stretch is technically valid but only meaningful on the cross axis — on the main axis it’s equivalent to Start.
CrossAlign
Where children sit on the cross axis. Options include Stretch.
AutoUI.Create() .Row().WidthFill().Height(60) .CrossAlign(Alignment.Center) // children vertically centered .Children(...) .Build();| Value | Effect |
|---|---|
Start | Top edge (Row) or left edge (Column) |
Center | Centered on cross axis |
End | Bottom edge (Row) or right edge (Column) |
Stretch | Children grow to fill the cross axis (override their cross-axis size) |
Stretch is the most useful one here — a Row of cards all stretching to the row’s full height regardless of their declared Height.
Center shorthand
.Center() is sugar for .MainAlign(Center).CrossAlign(Center):
AutoUI.Create() .WidthFill().HeightFill() .Center() .Children( AutoUI.Create().Width(200).Height(100).Text("Centered") ) .Build();The most common use: full-screen modal with a centered card.
MainDistribute (extra space)
When children don’t fill the main axis, MainDistribute decides how the leftover space is distributed between children rather than around the whole block.
| Value | Effect | Picture |
|---|---|---|
Packed (default) | Children clustered, gap = Gap literal | [A][B][C]_____ |
SpaceBetween | Equal gaps between children, none at edges | [A]___[B]___[C] |
SpaceAround | Equal gaps including half-gaps at edges | _[A]__[B]__[C]_ |
SpaceEvenly | Equal gaps including full-gaps at edges | __[A]__[B]__[C]__ |
AutoUI.Create().Row().WidthFill() .MainDistribute(Distribution.SpaceBetween) .Children( AutoUI.Create().Text("A"), AutoUI.Create().Text("B"), AutoUI.Create().Text("C") ) .Build();A pins to the left, C pins to the right, B sits in the middle. No WidthFill spacers needed.
Interaction with MainAlign: when MainDistribute is anything other than Packed, MainAlign is effectively ignored — distribution decides where children sit.
Per-child cross alignment
Override the parent’s CrossAlign for a single child via CrossAxisSelfAlign:
AutoUI.Create() .Row().HeightHug().CrossAlign(Alignment.Start) .Children( AutoUI.Create().Text("Top-aligned"), AutoUI.Create().Text("Override").CrossAxisSelfAlign(GridAlignment.End), AutoUI.Create().Text("Top-aligned again") ) .Build();CrossAxisSelfAlign takes a GridAlignment (different enum from Alignment):
| Value | Effect |
|---|---|
Auto | Inherit from parent’s CrossAxisAlign |
Start / Center / End | Override |
Stretch | Override to stretch |
The naming difference is historical — the per-item override predates the per-container CrossAlign. Treat the values as equivalent.
Grid alignment
Grid containers have their own alignment properties — see Grid:
| Property | What it does |
|---|---|
GridHorizontalAlign(GridAlignment) | How items sit horizontally in their cells (default Stretch) |
GridVerticalAlign(GridAlignment) | How items sit vertically in their cells (default Stretch) |
GridItemHorizontalAlign(GridAlignment) | Per-item override (default Auto) |
GridItemVerticalAlign(GridAlignment) | Per-item override (default Auto) |
These are conceptually parallel to MainAlign/CrossAlign but use the GridAlignment enum for consistency with CrossAxisSelfAlign.
Common patterns
Fully centered card
AutoUI.Create() .WidthFill().HeightFill() .Center() .Children( AutoUI.Create().Size(360, 200).Background(Color.gray) ) .Build();Header with title left, actions right
AutoUI.Create().Row().WidthFill().HeightHug().CrossAlign(Alignment.Center) .Children( AutoUI.Create().Text("Title", 24f), AutoUI.Create().WidthFill(), // spacer AutoUI.Create().Button("Save", OnSave), AutoUI.Create().Button("Cancel", OnCancel) ) .Build();CrossAlign(Center) keeps title and buttons vertically aligned despite different heights. The WidthFill() spacer separates the title-block from the action-block.
Toolbar with even spacing
AutoUI.Create().Row().WidthFill().Height(48) .CrossAlign(Alignment.Center) .MainDistribute(Distribution.SpaceEvenly) .Children( AutoUI.Create().Button("File", OnFile), AutoUI.Create().Button("Edit", OnEdit), AutoUI.Create().Button("View", OnView), AutoUI.Create().Button("Help", OnHelp) ) .Build();Stretched row of cards (uniform height)
AutoUI.Create().Row().WidthFill().HeightHug() .CrossAlign(Alignment.Stretch) // all cards take row's full height .Gap(12) .Children( Card1(), Card2(), Card3() ) .Build();Each card declares whatever Height it wants — Stretch overrides them all to match the tallest sibling.