Build responsive Flutter layouts from the constraint system outward. Prefer simple flex composition and introduce fixed dimensions or overlays only when the design requires them for a concrete purpose.
Layout workflow
- Identify each group as primarily vertical, horizontal, overlapping, scrolling, or wrapping.
- Start vertical groups with
Columnand horizontal groups withRow. - Nest small, named widgets instead of building one deeply nested
buildmethod. - Use
Expanded,Flexible, andSpacerto distribute bounded free space. - Add padding, alignment, aspect ratio, and constraints intentionally.
- Test narrow and wide constraints, text scaling, keyboard appearance, and long or localized content.
Rules
- Prefer
Columnfor vertical flow andRowfor horizontal flow. - Control alignment with
mainAxisAlignment,crossAxisAlignment, andmainAxisSize. - Use
Expandedwhen a child must fill its allocated share of remaining main-axis space. - Use
Flexiblewhen a child may use less than its allocated share. - Use
flexonly to express proportional allocation. A child withflex: 2receives twice the free-space share of a sibling withflex: 1. - Use
Spacerfor flexible separation between siblings. UseSizedBoxfor deliberate, fixed gaps. - Wrap text or other variable-width content in
ExpandedorFlexibleinside aRowwhen it must yield space to siblings. - Use
ListViewor another scrollable when vertical content can exceed the viewport;Columndoes not scroll. - Use
Wrapwhen horizontal children should move onto another run instead of shrinking or overflowing. - Use
LayoutBuilder, breakpoints, or adaptive widgets when the composition itself must change with available space. - Use
SafeAreawhen content must avoid system intrusions.
Avoid rigid layouts
Avoid these as default layout mechanisms:
Stackwith hardcodedPositionedcoordinatesContainer,SizedBox, orConstrainedBoxwith hardcoded screen-like width or height- offsets, transforms, or margins used to simulate normal document flow
- screen dimensions copied from a mockup
Use them when they serve a concrete purpose, such as:
- true visual overlap, badges, floating controls, or anchored decoration
- touch-target minimums, icon sizes, thumbnails, or bounded media
- intentional maximum reading width
- aspect-ratio requirements
- platform or design-system constants
State the purpose in the code structure or a brief comment when it is not obvious.
Constraint safety
- Put
ExpandedandFlexibleonly underRow,Column, orFlex. - Do not use non-zero flex along an unbounded main axis. In a vertical scrollable, remove vertical
ExpandedorFlexible, or establish a meaningful finite constraint. - Fix a nested
Columnthat needs the outer column's remaining height by wrapping the inner column inExpanded. - Diagnose overflow by inspecting constraints and variable content before adding clipping or smaller hardcoded sizes.
- Prefer scrolling for content that legitimately exceeds available space.
Preferred pattern
Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Header(),
const SizedBox(height: 16),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Flexible(flex: 2, child: PrimaryContent()),
const SizedBox(width: 16),
const Flexible(child: SecondaryContent()),
],
),
),
const SizedBox(height: 16),
const Actions(),
],
),
)
Change this composition at a breakpoint if the horizontal content cannot remain usable on a narrow screen; do not merely squeeze it.
Visual references
Inspect these diagrams when decomposing a mockup into nested flex layouts:
- Pavlova Row and Column layout shows the overall horizontal
Rowcontaining a vertical contentColumnand an image. - Nested Row and Column diagram shows smaller rating and icon groups decomposed into nested
RowandColumnwidgets.
Use the diagrams as structural references, not as fixed pixel templates.
Verification
- Confirm no RenderFlex overflow at supported viewport sizes.
- Confirm text wraps or truncates intentionally.
- Confirm flexible children receive bounded constraints.
- Confirm scrollable content remains reachable.
- Confirm fixed sizes and
StackorPositionedusages have a concrete design reason.