Layouts in Depth
Row and Column: the workhorses
Most layouts are built from Row (horizontal) and Column (vertical). You control how children are spaced and aligned with two properties:
- mainAxisAlignment — position along the layout direction (the main axis).
- crossAxisAlignment — position across it.
Column(
mainAxisAlignment: MainAxisAlignment.center, // vertical centering
crossAxisAlignment: CrossAxisAlignment.start, // left-align children
children: [
Text('Profile', style: TextStyle(fontSize: 20)),
Row(children: const [
Icon(Icons.star, color: Colors.amber),
SizedBox(width: 4),
Text('4.8 rating'),
]),
],
)
For a Column the main axis is vertical; for a Row it’s horizontal. Keeping this straight is the key to predictable layouts.
Container: the multi-tool
Container combines padding, margin, color, borders, rounded corners and sizing in one widget — perfect for cards and boxes.
Container(
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration(
color: const Color(0xFFF3EEFE),
borderRadius: BorderRadius.circular(12),
boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 8)],
),
child: const Text('Card content'),
)
Sharing space with Expanded and Flexible
Inside a Row or Column, Expanded makes a child grow to fill the remaining space. Use the flex value to split space proportionally.
Row(children: [
Expanded(flex: 2, child: Container(color: Colors.purple)), // 2/3
Expanded(flex: 1, child: Container(color: Colors.deepPurple)), // 1/3
])
This also fixes the classic “RenderFlex overflowed” error — wrapping a child in Expanded or Flexible lets it shrink to fit.
Stack for overlapping widgets
Stack(children: [
Image.network(url),
Positioned(
bottom: 8, right: 8,
child: Container(
color: Colors.black54,
padding: const EdgeInsets.all(4),
child: const Text('NEW', style: TextStyle(color: Colors.white)),
),
),
])
Spacing helpers
- SizedBox — fixed empty space (
SizedBox(height: 12)). - Padding — space around a child.
- Spacer — flexible gap inside a Row/Column.
Common mistakes
- “RenderFlex overflowed” — a child is too big; wrap it in
Expanded/Flexibleor use a scroll view. - Confusing main-axis and cross-axis alignment.
- Reaching for
Containerjust to add padding — usePaddingwhen that’s all you need.
Summary: Build layouts with Row/Column (controlled by main/cross-axis alignment), style boxes with Container, share space with Expanded/Flexible, overlap with Stack, and add gaps with SizedBox/Padding.