Row & Column

Row and Column are the most fundamental layout widgets. They allow you to arrange multiple child widgets in a flexible way, either horizontally or vertically. Mastering them is the key to building almost any user interface.

  • The Row widget arranges its children horizontally.

  • The Column widget arranges its children vertically.

Core Concepts

1. Main Axis vs. Cross Axis

The core concept to understand when working with Row and Column is the axis direction:

  • Main Axis: The primary direction of arrangement. For a Row, it's horizontal. For a Column, it's vertical.

  • Cross Axis: The direction perpendicular to the main axis. For a Row, it's vertical. For a Column, it's horizontal.

    A diagram showing the Main Axis and Cross Axis for a Row (horizontal/vertical) and a Column (vertical/horizontal).
    The Main and Cross axes for Row and Column widgets.

    All alignment and sizing properties operate based on these two axes.

2. Static vs. Dynamic Children

A Row or Column can be populated with widgets in two ways. You can add a fixed number of widgets individually in the builder (Static Children), or you can generate a list of widgets from a data source (Dynamic Children). This flexibility allows you to build both fixed layouts and data-driven, repeating lists.

Learn more about Static and Dynamic Children here.


Common Properties

The properties for Row and Column are identical and determine how their children are positioned and sized.

Main Axis Alignment

This property defines how the free space is distributed between children along the main axis.

A visual comparison of Main Axis Alignment options for a Row, showing horizontal distribution of items.
Main Axis Alignment in a Row (controls horizontal spacing).
A visual comparison of Main Axis Alignment options for a Column, showing vertical distribution of items.
Main Axis Alignment in a Column (controls vertical spacing).
Value
Description

Start

Places children at the beginning of the main axis.

Center

Places children in the middle of the main axis.

End

Places children at the end of the main axis.

Space Between

Distributes children evenly, with no space at the start or end.

Space Around

Distributes children evenly, with half the spacing at the start and end as between them.

Space Evenly

Distributes children with equal spacing between all items, including at the start and end.

Cross Axis Alignment

This property defines how children are positioned relative to each other along the cross axis.

A visual comparison of Cross Axis Alignment options for a Row, showing vertical alignment of items.
Cross Axis Alignment in a Row (controls vertical alignment).
A visual comparison of Cross Axis Alignment options for a Column, showing horizontal alignment of items.
Cross Axis Alignment in a Column (controls horizontal alignment).
Value
Description

Start

Aligns children to the beginning of the cross axis.

Center

Aligns children to the center of the cross axis.

End

Aligns children to the end of the cross axis.

Stretch

Stretches each child to fill the available space along the cross axis.

Main Axis Size

This property determines how much space the Row or Column should occupy along its main axis.

A visual comparison of Main Axis Size: Max vs. Min.
Max fills available space, while Min shrinks to fit its children.
Value
Description

Max

The widget expands to fill all available space along its main axis. This is the default.

Min

The widget shrinks to fit the combined size of its children along the main axis.

Scrollable

If the content of a Row or Column exceeds its available space, enabling the Scrollable property will allow users to scroll through the content. This is essential for creating scrollable lists or carousels.

Spacing

These properties allow you to add fixed spacing along the main axis, offering an alternative to using Main Axis Alignment for space distribution.

A diagram illustrating Item Spacing, Start Spacing, and End Spacing in a Row and Column.
Use spacing properties for precise control over gaps between children.
Property
Description

Item Spacing

The amount of empty space to place between each child widget along the main axis.

Start Spacing

The amount of empty space to place before the first child widget along the main axis.

End Spacing

The amount of empty space to place after the last child widget along the main axis.


Children: Static vs. Dynamic

You can populate a Row or Column with child widgets in two ways:

1. Static Children

Add a fixed number of child widgets directly in the builder. Each child you add will appear in the widget tree, and its properties can be configured individually. This is ideal for layouts where the number of items is known and doesn't change.

2. Dynamic Children

To generate children from a list of data, you can use the Data Source property. This turns the Row or Column into a powerful list builder.

  1. Enable the Data Source toggle in the properties panel.

  2. Provide data by either entering a fixed JsonArray in the JSON editor or binding it to an expression that returns a JsonArray (e.g., from an API call or App State).

  3. Add a single child widget to the Row or Column. This widget acts as a template that will be repeated for each item in the data source.

  4. Inside this template child, use the currentItem variable to access the data for each item.

    • If your data is a list of objects (e.g., [{"name": "Apple"}, {"name": "Banana"}]), access properties with dot notation: ${currentItem.name}.

    • If your data is a list of simple values (e.g., ["Apple", "Banana"]), currentItem refers to the value itself: ${currentItem}.

This is perfect for building small, repeating UI elements like a row of filter chips, a list of user avatars, or a set of feature icons.


Controlling Child Size: Expanded & Flexible

When you have static children inside a Row or Column, you can control how they occupy the remaining space along the main axis. After placing children, you can find the Children Flex section in the properties panel of the Row or Column itself. Here, you can individually configure the expansion type for each child.

Note: The Children Flex setting only applies to static children. It has no effect when children are generated dynamically from a data source.

An illustration of how Expanded and Flexible children behave in a Row, showing how they share space.
Use expansion properties to control how children share space along the main axis.

Expansion Types

Type
Name in Properties
Description

Expanded

Tight

Forces the child to fill all remaining empty space along the main axis. If multiple children are set to Tight, the space is divided according to their Flex Value.

Flexible

Loose

Allows the child to expand into the remaining space, but does not force it to. The child will grow no larger than its flex value allows, but can be smaller if its content is smaller.

None

None

The child takes up only its intrinsic (natural) size. It will not be expanded or flexed. This is the default.

Flex Value

When you set a child's expansion Type to Loose or Tight, the Flex Value (a number) determines its share of the remaining space relative to its siblings.

  • A child with Flex Value: 2 will take up twice as much space as a sibling with Flex Value: 1.

  • If all expanded children have Flex Value: 1, they will share the space equally.

  • A child with Flex Value: 2 will take up twice as much space as a sibling with Flex Value: 1.

  • If all expanded children have Flex Value: 1, they will share the space equally.

Expanded vs. Flexible: A Deeper Dive

While both Expanded and Flexible use the Flex Value to claim a share of the remaining space, their behavior is fundamentally different. Understanding this difference is crucial for mastering layouts.

The Key Difference: Forcing vs. Allowing

  • Expanded (Tight) forces a child to fill the space. It's a rigid rule. The child's own intrinsic size is ignored, and it expands to occupy the full share of remaining space defined by its Flex Value.

  • Flexible (Loose) allows a child to fill the space. It's a flexible rule. The child can grow up to its share of the remaining space, but if its content is smaller, it will only take up the space it needs.

Here’s a summary of what each can do that the other cannot:

Feature

Expanded (Tight)

Flexible (Loose)

Behavior

Forces the child to fill its share of remaining space.

Allows the child to fill its share of remaining space, but doesn't force it.

Sizing

The child's size is determined by the Flex Value and remaining space. Its own content size is ignored.

The child's size is the smaller of its content size and its allocated flex space.

What it can do

Force a small widget (like an icon) to grow and occupy a large area.

Allow a widget to be smaller than its potential flex space if its content doesn't need it.

When to Use Each

  • Use Expanded (Tight) when:

    • You need to divide the screen into proportional sections that always fill the available space (e.g., a 70/30 split for a main content area and a sidebar).

    • You want a specific widget to take up all the leftover space in a Row or Column, pushing other widgets to the edges.

    • You are creating a layout where the components must stretch to fit, regardless of their content size.

    Example: A Row with two Expanded children will always cause them to fill the full width of the Row.

  • Use Flexible (Loose) when:

    • You want a widget (like a Text widget) to have room to grow if its content is long, but you don't want to force it to be huge if the content is short.

    • You have a widget with a natural size, but you want it to expand slightly if there's extra space, without taking over the layout.

    • You want to give a widget a "max-width" or "max-height" that is proportional to the remaining space.

    Example: In a Row, a Button with Flexible will keep its normal size if there's no extra space, but will expand to fill some of the remaining space if the Row is wider than its children.


Default Properties

The Row and Column widgets support all Default Properties, such as Visibility, Padding, Margin, and Background Color.

Last updated