Question #358MediumWidgets & UI

What is the difference between Flexible and Expanded?

#widgets#layout#flexible#expanded

Answer

Overview

Both

text
Flexible
and
text
Expanded
are widgets that control how children of
text
Row
,
text
Column
, or
text
Flex
fill available space. The key difference is that Expanded forces a child to fill available space, while Flexible allows a child to shrink or grow within constraints.


Expanded - Forces Child to Fill Space

text
Expanded
is a shorthand for
text
Flexible(fit: FlexFit.tight)
. It forces the child to fill all available space in the main axis.

dart
Column(
  children: [
    Expanded(
      child: Container(color: Colors.red), // Takes all available space
    ),
    Container(color: Colors.blue, height: 100), // Fixed height
  ],
)

Result: Red container fills the remaining vertical space after the blue container's 100px.


Flexible - Allows Child to Size Within Constraints

text
Flexible
allows the child to size itself within available space, but doesn't force it to fill everything.

dart
Column(
  children: [
    Flexible(
      child: Container(color: Colors.red, height: 50), // Can shrink if needed
    ),
    Container(color: Colors.blue, height: 100),
  ],
)

Result: Red container takes its preferred 50px height (doesn't expand).


Key Differences

FeatureExpandedFlexible
Fit mode
text
FlexFit.tight
text
FlexFit.loose
(default)
BehaviorForces child to fill available spaceAllows child to size within constraints
Child sizingIgnores child's size preferencesRespects child's size if space available
OverflowPrevents overflowMay overflow if child is too large
Use caseWhen you want child to fill spaceWhen you want flexible sizing

FlexFit Comparison

dart
// Expanded = Flexible with tight fit
Expanded(child: Widget) 
// Equivalent to:
Flexible(fit: FlexFit.tight, child: Widget)

// Flexible = loose fit by default
Flexible(child: Widget)
// Equivalent to:
Flexible(fit: FlexFit.loose, child: Widget)

Practical Examples

Example 1: Multiple Expanded Widgets

dart
Row(
  children: [
    Expanded(
      flex: 2,
      child: Container(color: Colors.red), // Takes 2/3 of width
    ),
    Expanded(
      flex: 1,
      child: Container(color: Colors.blue), // Takes 1/3 of width
    ),
  ],
)

Example 2: Flexible with Intrinsic Size

dart
Row(
  children: [
    Flexible(
      child: Text(
        'Short text', 
        overflow: TextOverflow.ellipsis,
      ), // Takes only needed width
    ),
    Icon(Icons.info),
  ],
)

Example 3: Mixed Usage

dart
Column(
  children: [
    Flexible(
      child: Text('This can shrink if needed'),
    ),
    Expanded(
      child: ListView.builder(...), // Fills remaining space
    ),
    Container(height: 60), // Fixed bottom bar
  ],
)

The flex Property

Both widgets accept a

text
flex
parameter that controls the proportion of available space they take.

dart
Row(
  children: [
    Expanded(flex: 1, child: Container(color: Colors.red)),
    Expanded(flex: 2, child: Container(color: Colors.blue)),
    Expanded(flex: 1, child: Container(color: Colors.green)),
  ],
)

Result: Blue takes 50% of width (2/4), red and green each take 25% (1/4).


When to Use Which

ScenarioUse
Child should fill all available space
text
Expanded
Child should take only needed space
text
Flexible
Prevent overflow in Row/Column
text
Expanded
or
text
Flexible
Create proportional layoutsBoth with
text
flex
Wrap Text that might overflow
text
Flexible
with
text
overflow
ListView/GridView in Column
text
Expanded

Common Pitfalls

dart
// ❌ Wrong - Unbounded height error
Column(
  children: [
    ListView.builder(...), // Error: unbounded height
  ],
)

// ✅ Correct - Use Expanded
Column(
  children: [
    Expanded(
      child: ListView.builder(...), // Works: bounded height
    ),
  ],
)

// ❌ Wrong - Text overflow
Row(
  children: [
    Text('Very long text that will overflow...'),
    Icon(Icons.arrow_forward),
  ],
)

// ✅ Correct - Use Flexible or Expanded
Row(
  children: [
    Flexible(
      child: Text(
        'Very long text that will overflow...',
        overflow: TextOverflow.ellipsis,
      ),
    ),
    Icon(Icons.arrow_forward),
  ],
)

Summary

Expanded = "Fill all available space" (tight fit)

Flexible = "Take space if available, but don't force" (loose fit)

Both prevent overflow and work with

text
flex
for proportional layouts.

For more details, see Flutter Layout Widgets.