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.
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.
dart
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:
dart
// Column on mobile, row-reverse on md+
WDiv(className:'flex flex-col md:flex-row-reverse gap-4')
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])
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.
Use wrap to create a wrapping layout (Flutter's Wrap widget).
dart
// 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')),// ...
],)
A child that grows turns the automatic Flexible wrap off. Space distribution wraps each row child in a Flexible so it can shrink, mirroring the CSS flex: 0 1 auto default. Flutter shares free space equally between flex children, though, so that wrap also hands a share to a sibling that never asked for one: a justify-between row holding a flex-1 title and a 24 px icon split 400 px down the middle, and the title rendered at 200 px with 176 px sitting blank beside the icon. So when any child claims a grow share (flex-1, flex-{n}, grow, flex-grow, flex-auto, a bare w-full, or a raw Expanded / Flexible), the wrap is skipped and the growing child takes the whole remainder while its siblings keep their content width, which is what CSS justify-content: space-between does. There is nothing left to distribute once a child grows, so the wrap was only ever about shrinking. Three exceptions: overflow-hidden keeps the wrap unconditionally because that token asks for shrinking on purpose, the shrink-only tokens (shrink, flex-shrink, flex-initial) are not a grow claim, and a PREFIXED grow token (hover:flex-1, md:grow) is not one either. A prefixed token is conditional, and the row cannot tell from the class string whether the variant is active, so treating it as a claim would strip the shrink wrap off every sibling at a breakpoint where nothing grows. Use an unprefixed flex-1 when you want the child to own the remainder.
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
dart
// Vertically center items in a row
WDiv(className:'flex items-center h-20')
Column cross-axis stretch (default AND explicit items-stretch). A flex flex-col with no explicit items-* token, OR with an explicit items-stretch, stretches each WDiv, WAnchor (any child), and WButton child that does not control its own width to the column width, matching CSS align-items: stretch. Explicit items-stretch therefore equalizes child widths (every eligible child fills the column), closing the asymmetry with grid ... items-stretch. For WAnchor: when the anchor wraps a WDiv, the inner WDiv's className decides (so WAnchor > WDiv(w-32) keeps 128 px; a WAnchor > WDiv with a self-flex token is excluded just as a direct self-flexing WDiv is); when the anchor wraps a WText or raw widget, the anchor stretches by policy so its tap surface fills the column. Left untouched: children with an explicit width (w-* / min-w-* / max-w-* / w-full, in any state/breakpoint variant), children that self-wrap in Expanded/Flexible (grow, flex-grow, flex-auto, flex-initial, shrink, flex-shrink, flex-N), basis-* children, absolute children, bare WText leaves, and raw Flutter widgets. shrink-0 / flex-none children still stretch on the cross axis (flex-shrink is main-axis only, matching CSS). Add items-start / items-center / items-end to turn stretch off and let children size to content. Rows are never auto-stretched on the cross axis. When the column itself sits in an unbounded-width context (a bare Row slot, UnconstrainedBox, horizontal scroll), the stretch safely falls back to content-sized children instead of forcing an infinite width.
Layout stability: wind's flex is intrinsic-safe. Flutter's IntrinsicHeight and IntrinsicWidth perform an intrinsic-dimension pass that reads child sizes mid-layout, and a LayoutBuilder on that path asserts LayoutBuilder does not support returning intrinsic dimensions. Wind's flex uses NO LayoutBuilder, and neither does h-full since it became the WindFullHeightBox render object: column cross-axis stretch is a real render object (WindCrossStretch), and basis-* resolves against the flex's own extent via a WindMainExtentProvider (see lib/src/widgets/w_div.dart and wind_equal_height_row.dart). So a flex flex-col (with or without basis-*) renders correctly inside an items-stretch grid cell, under an IntrinsicHeight/IntrinsicWidth, or in a Table cell without asserting. For a connector, rail, or divider that must fill the cross axis to match the tallest sibling, prefer a Stack with a Positioned(top: 0, bottom: 0) line, or use wind's own items-stretch column (also intrinsic-free and animation-safe).
dart
// Safe connector pattern: Stack + Positioned, no IntrinsicHeight
Stack(
children: [
Row(children: [leftContent, rightContent]),Positioned(
top:0, bottom:0, left: connectorX, width:2, child:ColoredBox(color: railColor), ), ],)
// Or let wind do the stretch safely:
WDiv(className:'flex flex-col items-stretch gap-4')
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
Tailwind's shorthand self-start / self-end / self-center / self-stretch / self-auto is accepted as an alias for the matching align-self-* class, so either form works.
dart
WDiv(
className:'flex items-start h-20', children: [
WDiv(className:'...'),// This item centers itself (self-center is shorthand for align-self-center)
WDiv(className:'self-center ...'), ],)
Control how individual children resize to fill available space.
Class
Description
flex-1
Allow child to grow and fill available space (Expanded).
flex-grow / grow
Alias for flex-1 (Tailwind v3 and v4 names).
grow-0
Do not grow: child keeps its intrinsic main-axis size.
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
CSS flex: 0 0 auto: do not grow AND do not shrink. Keeps intrinsic size (same no-shrink path as shrink-0).
basis-1/2 / basis-1/3 / basis-1/4 / basis-full
Fractional flex-basis: initial main-axis size (width in a row, height in a column). Approximates CSS flex-basis; ignores grow/shrink interplay.
basis-[Npx]
Fixed flex-basis: a fixed main-axis size in logical pixels (e.g., basis-[120px]).
w-full on a Row child is treated as flex-1. A flex flex-row hands non-flex children an unbounded main-axis width, so a bare w-full child would otherwise assert RenderBox was not laid out. Wind now wraps such a child in Expanded, so w-full fills the row exactly like flex-1. Prefer flex-1 for clarity; reach for w-full only when sharing a className across row and non-row contexts. A prefixed md:w-full is not auto-expanded (use md:flex-1).
Previewlayout/flex_growThe live demo is not available for this example.flex_grow.dartView sourcedart
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":
dart
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.
This site uses Google Analytics cookies to see which pages get read and how far, and which links, copy buttons and docs searches get used. They load only if you accept.