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')),// ...
],)
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 default: smart cross-axis stretch. A flex flex-col with no explicit items-* token 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. 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), 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 any items-* token (e.g. items-start) to turn this 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: avoid IntrinsicHeight / IntrinsicWidth in animated subtrees. Flutter's IntrinsicHeight and IntrinsicWidth perform an intrinsic-dimension pass that reads child sizes mid-layout. Inside a sheet or route open animation (e.g. DraggableScrollableSheet, PageRouteBuilder) this lands a RenderBox was not laid out assertion because the animation drives a frame before intrinsics resolve. For a connector, rail, or divider that must fill the cross axis to match the tallest sibling, use a Stack with a Positioned(top: 0, bottom: 0) line instead, or use wind's own items-stretch column which is intrinsic-free and animation-safe. Wind itself uses no IntrinsicHeight or IntrinsicWidth; its smart column stretch is LayoutBuilder + SizedBox(width: double.infinity) (see lib/src/widgets/w_div.dart).
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 ...'), ],)
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.