Flexbox & Layout
Utilities for controlling flex containers, direction, alignment, wrapping, and spacing.
- Basic Usage
- Quick Reference
- Flex Direction
- Reversing Direction
- Child Order
- Wrapping
- Justify Content
- Align Items
- Align Content
- Align Self
- Flex, Grow & Shrink
- Gap & Spacing
- Responsive Design
- Arbitrary Values
- Customizing Theme
- Flex Children Inside a Scrollable Axis
- Related Documentation
// Basic flex row
WDiv(className: 'flex gap-4 items-center')
// Vertical column
WDiv(className: 'flex flex-col gap-2')
Basic Usage
Flexbox in Wind mirrors CSS Flexbox behavior but maps to Flutter's Row and Column widgets. Use flex to initialize a flex container, then apply utilities to control direction, alignment, and spacing.
WDiv(
className: 'flex flex-col md:flex-row justify-between items-center gap-4 p-6 bg-white',
children: [
WText('Logo'),
WDiv(
className: 'flex gap-2',
children: [
WText('Home'),
WText('About'),
],
),
],
)
Quick Reference
| Class | CSS Equivalent | Flutter Equivalent |
|---|---|---|
flex |
display: flex |
Row / Column |
wrap |
flex-wrap: wrap |
Wrap |
flex-row |
flex-direction: row |
Row() |
flex-col |
flex-direction: column |
Column() |
flex-row-reverse |
flex-direction: row-reverse |
Row(textDirection: mirrored) |
flex-col-reverse |
flex-direction: column-reverse |
Column(verticalDirection: up) |
order-{n} |
order: {n} |
Stable-sort children before layout |
justify-{alignment} |
justify-content: ... |
MainAxisAlignment |
items-{alignment} |
align-items: ... |
CrossAxisAlignment |
gap-{n} |
gap: {n} |
SizedBox (spacer) |
flex-1 |
flex: 1 |
Expanded() |
shrink-0 |
flex-shrink: 0 |
No wrapper — preserves intrinsic size |
Flex Direction
Control the axis of your layout.
// Row (Horizontal) - Default for 'flex'
WDiv(className: 'flex flex-row')
// Column (Vertical)
WDiv(className: 'flex flex-col')
Reversing Direction
Use flex-row-reverse or flex-col-reverse to reverse the main-axis direction. Rather than reversing the children list, Wind flips the axis itself (via Row.textDirection / Column.verticalDirection), so alignment tokens mirror correctly: justify-start anchors to what is now the visual end, matching CSS's flex-direction: *-reverse. Cross-axis alignment is unaffected.
WDiv(
className: 'flex flex-row-reverse gap-2',
children: [
WText('First in code'),
WText('Last in code'),
],
)
// Renders as: [Last in code] [First in code]
Responsive prefixes work as expected:
// Column on mobile, row-reverse on md+
WDiv(className: 'flex flex-col md:flex-row-reverse gap-4')
Child Order
Use order-* on individual flex children to override their paint order without changing the source order. The parent flex container stable-sorts children by their resolved order value before laying them out; children without order-* default to 0.
| Class | Behavior |
|---|---|
order-0 .. order-12 |
Explicit index (integers only) |
order-first |
Placed before everything else (sentinel -9999) |
order-last |
Placed after everything else (sentinel 9999) |
order-none |
Resets to 0 |
order-[n] |
Arbitrary integer (supports negative, e.g. order-[-3]) |
WDiv(
className: 'flex',
children: [
WDiv(className: 'order-3', child: WText('A')),
WDiv(className: 'order-1', child: WText('B')),
WDiv(className: 'order-2', child: WText('C')),
],
)
// Visual order: B, C, A
Responsive reordering is a common use case — swap the layout per breakpoint without duplicating children:
WDiv(
className: 'flex flex-col md:flex-row gap-4',
children: [
WDiv(className: 'order-2 md:order-1', child: WText('Sidebar')),
WDiv(className: 'order-1 md:order-2', child: WText('Main content')),
],
)
When combined with flex-*-reverse, children are sorted by order-* first; the container then flips the main-axis direction so justify-* still applies against the (now reversed) axis.
Wrapping
Use wrap to create a wrapping layout (Flutter's Wrap widget).
[!WARNING] Flutter's
RowandColumndo not wrap. You must use thewrapclass instead offlexif you want wrapping behavior.
// Items wrap to the next line when they run out of space
WDiv(
className: 'wrap gap-2',
children: [
WDiv(className: 'px-2 py-1 bg-gray-200 rounded', child: WText('Tag 1')),
WDiv(className: 'px-2 py-1 bg-gray-200 rounded', child: WText('Tag 2')),
// ...
],
)
Justify Content
Controls how children are distributed along the main axis (Horizontal for row, Vertical for col).
| Class | Flutter MainAxisAlignment |
|---|---|
justify-start |
start |
justify-end |
end |
justify-center |
center |
justify-between |
spaceBetween |
justify-around |
spaceAround |
justify-evenly |
spaceEvenly |
WDiv(
className: 'flex justify-between',
children: [
WDiv(className: 'w-10 h-10 bg-red-500'),
WDiv(className: 'w-10 h-10 bg-blue-500'),
],
)
Align Items
Controls how children are distributed along the cross axis (Vertical for row, Horizontal for col).
| Class | Flutter CrossAxisAlignment |
|---|---|
items-start |
start |
items-end |
end |
items-center |
center |
items-baseline |
baseline |
items-stretch |
stretch |
// Vertically center items in a row
WDiv(className: 'flex items-center h-20')
Align Content
Only applicable when using wrap. Controls how lines of wrapped content are aligned.
| Class | Flutter WrapAlignment |
|---|---|
align-content-start |
start |
align-content-end |
end |
align-content-center |
center |
align-content-between |
spaceBetween |
align-content-around |
spaceAround |
align-content-evenly |
spaceEvenly |
align-content-stretch |
start (Flutter limitation) |
Align Self
Control alignment of an individual flex item, overriding the container's items-* setting.
| Class | Flutter Alignment |
|---|---|
align-self-start |
topCenter |
align-self-end |
bottomCenter |
align-self-center |
center |
align-self-stretch |
center |
align-self-auto |
center |
WDiv(
className: 'flex items-start h-20',
children: [
WDiv(className: '...'),
// This item centers itself
WDiv(className: 'align-self-center ...'),
],
)
Flex, Grow & Shrink
Control how individual children resize to fill available space.
| Class | Description |
|---|---|
flex-1 |
Allow child to grow and fill available space (Expanded). |
flex-grow |
Alias for flex-1. |
flex-{n} |
Specific flex factor (e.g., flex-2). |
shrink |
Allow child to shrink if needed (FlexFit.loose). |
shrink-0 |
Preserve intrinsic size — no Flexible wrapper, child keeps its natural dimensions. |
flex-none |
Do not grow or shrink. |
WDiv(
className: 'flex',
children: [
// Sidebar: Fixed width, won't shrink
WDiv(className: 'w-16 shrink-0 bg-gray-200'),
// Content: Fills remaining space
WDiv(
className: 'flex-1 bg-white p-4',
child: WText('Main Content'),
),
],
)
Gap & Spacing
Wind's gap utilities add space between flex or grid items without using margin on the children themselves.
| Class | Value (Default) | Description |
|---|---|---|
gap-0 |
0px | No gap |
gap-1 |
4px | Small gap |
gap-2 |
8px | Medium gap |
gap-4 |
16px | Large gap |
gap-x-{n} |
- | Horizontal gap only |
gap-y-{n} |
- | Vertical gap only |
[!NOTE]
space-x-{n}andspace-y-{n}are supported as aliases forgap, butgapis preferred for consistency with Grid.
// 16px gap horizontally and vertically
WDiv(className: 'flex gap-4')
// 8px horizontal, 16px vertical
WDiv(className: 'flex flex-col gap-x-2 gap-y-4')
Responsive Design
Change layout direction or spacing based on screen size. This is extremely powerful for mobile-first designs.
// Column on mobile, Row on tablet+
WDiv(className: 'flex flex-col md:flex-row gap-4 md:gap-8')
Arbitrary Values
Need a specific gap or flex value not in the theme? Use bracket notation.
// Specific 23px gap
WDiv(className: 'flex gap-[23px]')
// Specific pixel gap
WDiv(className: 'flex gap-[1.5rem]')
Customizing Theme
To change the default spacing scale used by gap, modify baseSpacingUnit or the containers map in WindThemeData.
WindThemeData(
baseSpacingUnit: 8.0, // Now gap-1 = 8px, gap-2 = 16px
)
Flex Children Inside a Scrollable Axis
When a flex container's own main axis is scrollable (flex-row with overflow-x-auto|scroll, or flex-col with overflow-y-auto|scroll), Flutter's Expanded/Flexible cannot resolve — the incoming constraint is unbounded. Wind detects this at resolution time and skips the Expanded/Flexible wrap for direct flex children in that pass, so flex-N becomes a no-op while the axis is scrollable.
This enables the common responsive pattern of "scroll on narrow, distribute on wide":
WDiv(
className: 'flex flex-row gap-1 overflow-x-auto sm:overflow-visible',
children: [
for (final tab in tabs)
WDiv(className: 'flex-1', child: _tabBtn(tab)),
],
)
At base the row scrolls horizontally and children keep their intrinsic width. At sm+ the overflow is removed and flex-1 distributes width equally. Nested non-scrolling flex subtrees under a scrolling ancestor behave normally.