Flutter is a framework that emphasizes flexible, responsive layouts. Among its layout widgets, Flex plays a central role as the base class for Row and Column. While Row and Column are more commonly used, understanding Flex gives developers deeper control over flexible layouts, allowing them to implement more advanced UI structures.
This article will provide a comprehensive guide to the Flex widget, including:
- What the Flex widget is
- Key properties and how they work
- Flex directions and control
- Using Expanded and Flexible with Flex
- Differences between Flex, Row, and Column
- Real-world examples and best practices
By the end, you will have a thorough understanding of Flex and know exactly when and how to use it for advanced Flutter layouts.
1. Introduction to Flex
In Flutter, Flex is a widget that arranges its children linearly. The linear arrangement can be horizontal or vertical, which is determined by the direction property.
- Row → Horizontal Flex (
Axis.horizontal) - Column → Vertical Flex (
Axis.vertical)
Flex allows you to control the space distribution among children more precisely than Row and Column, especially when combined with Flexible and Expanded widgets.
2. Why Use Flex Instead of Row or Column?
Row and Column are convenient, but they limit the direction:
- Row is always horizontal
- Column is always vertical
Flex allows developers to dynamically set the direction. This is useful when building adaptive layouts, where the orientation may change based on screen size or conditions.
Example: Adaptive Flex Direction
Flex(
direction: Axis.horizontal, // can switch to Axis.vertical dynamically
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 50, height: 50, color: Colors.green),
Container(width: 50, height: 50, color: Colors.blue),
],
)
Here, you can switch the direction programmatically instead of writing separate Row and Column widgets.
3. Properties of the Flex Widget
Flex has several properties that are key to creating responsive and controlled layouts:
- direction – Sets the main axis (Axis.horizontal or Axis.vertical).
- mainAxisAlignment – Aligns children along the main axis.
- crossAxisAlignment – Aligns children along the cross axis.
- mainAxisSize – Determines how much space the Flex widget occupies along its main axis.
- textDirection – Controls the text flow direction for horizontal layouts.
- verticalDirection – Controls the vertical flow for vertical layouts.
- clipBehavior – Determines how to handle overflowing content.
4. MainAxisAlignment in Flex
mainAxisAlignment distributes space along the main axis. Options include:
- start – Aligns children at the beginning.
- end – Aligns children at the end.
- center – Centers children along the axis.
- spaceBetween – Places equal space between children.
- spaceAround – Equal space around each child.
- spaceEvenly – Equal space before, between, and after children.
Example:
Flex(
direction: Axis.horizontal,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 50, height: 50, color: Colors.green),
Container(width: 50, height: 50, color: Colors.blue),
],
)
The three containers are evenly spaced horizontally.
5. CrossAxisAlignment in Flex
crossAxisAlignment controls alignment perpendicular to the main axis.
Options include:
- start – Align to the start of the cross axis.
- end – Align to the end of the cross axis.
- center – Center along the cross axis.
- stretch – Expand children to fill the cross axis.
- baseline – Align text baseline for textual widgets.
Example:
Flex(
direction: Axis.horizontal,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(width: 50, height: 100, color: Colors.red),
Container(width: 50, height: 50, color: Colors.green),
Container(width: 50, height: 75, color: Colors.blue),
],
)
The containers align at the top edge of the Flex widget.
6. MainAxisSize in Flex
mainAxisSize determines how much space the Flex widget itself occupies along the main axis:
- MainAxisSize.min – Flex takes the minimum space required by its children.
- MainAxisSize.max – Flex expands to fill the available space.
Example:
Flex(
direction: Axis.vertical,
mainAxisSize: MainAxisSize.max,
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 50, height: 50, color: Colors.green),
],
)
The Flex widget now expands vertically to fill its parent.
7. Using Expanded and Flexible with Flex
Expanded
Expanded makes a child fill the available space along the main axis:
Flex(
direction: Axis.horizontal,
children: [
Expanded(child: Container(color: Colors.red, height: 50)),
Expanded(child: Container(color: Colors.green, height: 50)),
Expanded(child: Container(color: Colors.blue, height: 50)),
],
)
All three containers take equal horizontal space.
Flexible
Flexible allows a child to take only the space it needs or a proportion of available space.
Flex(
direction: Axis.horizontal,
children: [
Flexible(flex: 2, child: Container(color: Colors.red, height: 50)),
Flexible(flex: 1, child: Container(color: Colors.green, height: 50)),
],
)
The red container gets twice the space of the green container.
8. Differences Between Flex, Row, and Column
- Flex is the base class.
- Row = Flex(horizontal), Column = Flex(vertical).
- Flex allows dynamic direction switching.
- Flex is useful for adaptive or programmatically controlled layouts.
9. Real-World Use Cases of Flex
- Adaptive Layouts – Change orientation based on screen width.
- Proportional Space Distribution – Use flex property for flexible sizing.
- Complex UI – Nest Flex widgets for grids and dashboard layouts.
- Dynamic Direction – Switch between vertical and horizontal layouts.
10. Nesting Flex Widgets
Flex widgets can be nested to create advanced layouts:
Flex(
direction: Axis.vertical,
children: [
Flex(
direction: Axis.horizontal,
children: [
Expanded(child: Container(color: Colors.red, height: 50)),
Expanded(child: Container(color: Colors.green, height: 50)),
],
),
Container(height: 100, color: Colors.blue),
],
)
This creates a vertical layout with a horizontal section at the top.
11. Using Flex with MediaQuery
Flex works well for responsive designs:
Flex(
direction: MediaQuery.of(context).size.width > 600 ? Axis.horizontal : Axis.vertical,
children: [
Container(width: 100, height: 100, color: Colors.red),
Container(width: 100, height: 100, color: Colors.green),
],
)
Switches between horizontal and vertical based on screen width.
12. Combining Flex with Other Widgets
Flex can be wrapped inside Padding, Container, Card, or Center widgets.
Example:
Container(
padding: EdgeInsets.all(16),
child: Flex(
direction: Axis.horizontal,
children: [
Expanded(child: Container(color: Colors.red, height: 50)),
Expanded(child: Container(color: Colors.green, height: 50)),
],
),
)
13. Common Mistakes
- Using Row or Column when Flex would allow dynamic switching.
- Forgetting to use Expanded or Flexible with Flex children.
- Deep nesting of Flex widgets without refactoring.
- Misusing mainAxisSize and alignment, causing layout overflow.
14. Best Practices
- Use Flex when direction may change dynamically.
- Use Row or Column for fixed orientation layouts.
- Combine with Expanded and Flexible for proportional spacing.
- Always consider alignment and spacing to avoid overflow.
- Break complex Flex widgets into smaller, reusable widgets.
15. Real-World Example – Dashboard Layout
Flex(
direction: Axis.vertical,
children: [
Flex(
direction: Axis.horizontal,
children: [
Flexible(flex: 2, child: Container(color: Colors.red, height: 100)),
Flexible(flex: 1, child: Container(color: Colors.green, height: 100)),
],
),
Expanded(child: Container(color: Colors.blue)),
],
)
This layout could be a dashboard with top cards and a main content area.
16. Flex vs Stack
- Flex arranges children linearly.
- Stack overlays children.
- Use Flex for structured, proportional layouts.
- Use Stack for overlapping elements.
17. Flex with Scrollable Widgets
Flex can be wrapped inside SingleChildScrollView for scrollable layouts.
SingleChildScrollView(
child: Flex(
direction: Axis.vertical,
children: List.generate(20, (index) => Container(height: 50, color: Colors.primaries[index % Colors.primaries.length])),
),
)
18. Flex in Adaptive UI
Flex allows adaptive UIs where direction, spacing, and alignment can change based on device orientation.
- Horizontal for tablets
- Vertical for mobile phones
19. Summary of Flex Widget
- Flex = base class for Row & Column
- direction = horizontal or vertical
- Expanded and Flexible control child sizing
- Supports alignment, spacing, mainAxisSize
- Ideal for adaptive, proportional, and responsive layouts
Leave a Reply