flutter
/

Flutter Expanded Widget Tutorial for Beginners

Last Sync: Today

On this page

9
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

flutter

Flutter Expanded Widget Tutorial for Beginners

What is Expanded in Flutter?

Expanded is a widget that expands its child to fill the available space along the main axis of a Row, Column, or Flex. It's a shorthand for using Flexible with fit: FlexFit.tight. In simple terms, if you have a Row and you want one child to take all remaining space, wrap that child with Expanded.

Basic Usage

To use Expanded, place it inside a Row, Column, or Flex. Give it a child, and optionally a flex factor to control how much space it takes relative to other Expanded children.

DARTRead-only
1
Row(
  children: [
    Container(width: 50, color: Colors.red),
    Expanded(
      child: Container(color: Colors.green),
    ),
    Container(width: 50, color: Colors.blue),
  ],
)

Here, the red and blue containers have fixed widths, while the green one (wrapped in Expanded) fills all the remaining horizontal space.

How Expanded Works

Expanded is only useful inside a Row, Column, or Flex (collectively called flex parents). It tells the parent that this child should be forced to fill the available space along the main axis. The parent then divides the remaining space among all Expanded (and Flexible) children according to their flex values.

  • flex (default 1): An integer that determines the proportion of the remaining space this child should take. If you have two Expanded widgets with flex 1 and 2, the second one gets twice as much space.
  • child: The widget that will be forced to expand. It can be any widget (Container, Text, etc.) and will be constrained to fill the allocated area.

Expanded vs Flexible

Expanded is actually a specialized version of Flexible. The difference lies in how they treat the child's sizing:

  • Expanded uses FlexFit.tight, meaning the child is forced to fill the available space. If the child has its own size constraints, they are overridden.
  • Flexible uses FlexFit.loose by default, meaning the child can be smaller than the available space. It's allowed to size itself based on its own needs.
DARTRead-only
1
Row(
  children: [
    Flexible(
      fit: FlexFit.loose,
      child: Container(color: Colors.yellow, height: 50),
    ),
    Expanded(
      child: Container(color: Colors.orange, height: 50),
    ),
  ],
)

// The Flexible child may shrink if its content is small;
// the Expanded child always expands to fill the remaining space.

Using flex Factor

The flex property allows you to distribute space proportionally. This is essential for creating flexible layouts that adapt to different screen sizes.

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

// Total flex = 4. Red gets 2/4 of space, green gets 1/4, blue gets 1/4.

Common Use Cases

  • Making a widget fill remaining space in a Row/Column – The most common use.
  • Creating flexible navigation bars – e.g., a row of buttons with one taking all extra space to push others apart.
  • Building responsive forms – Input fields that stretch to fill available width.
  • Centering content while allowing it to grow – Combine Expanded with Center for dynamic sizing.

Common Mistakes Beginners Make

  • Using Expanded outside a Row/Column/Flex – Expanded must be a direct child of a flex widget. Placing it elsewhere (e.g., inside a Container) will cause a layout exception.
  • Putting multiple Expanded widgets with no constraints – If the parent Row/Column itself is unbounded (e.g., inside a ListView without setting shrinkWrap), Expanded won't know how much space to take and will throw an error.
  • Assuming Expanded respects the child's intrinsic size – Expanded forces its child to fill the space; if you need the child to be smaller, use Flexible with FlexFit.loose.
  • Confusing main axis direction – Remember that Expanded works along the main axis of the parent. For a Row, it expands horizontally; for a Column, vertically.
  • Forgetting that flex values are relative – They only matter in relation to other flex children. A single Expanded with flex 2 behaves exactly like flex 1.

Key Points to Remember

  • Expanded must be a direct child of a Row, Column, or Flex.
  • It forces its child to fill the available space along the main axis.
  • Use flex to distribute space proportionally among multiple Expanded widgets.
  • Expanded is a shorthand for Flexible(fit: FlexFit.tight).
  • For children that should not be forced to fill, use Flexible with FlexFit.loose.

Common Interview Questions

  1. What is the difference between Expanded and Flexible?
  2. Can you use Expanded inside a Container? Why or why not?
  3. How does the flex property work? If you have three Expanded widgets with flex 1, 2, and 3, how much space does each get?
  4. What happens if you put an Expanded widget inside a Column that is itself inside another Expanded? Explain the constraints.
  5. How would you create a layout where two widgets share the available space in a 3:1 ratio?
  6. Why might you get a "RenderFlex children have non-zero flex but incoming height constraints are unbounded" error? How do you fix it?

Try it yourself

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Expanded Example')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                height: 100,
                color: Colors.grey[300],
                child: Row(
                  children: [
                    Expanded(
                      flex: 2,
                      child: Container(color: Colors.red),
                    ),
                    Expanded(
                      flex: 1,
                      child: Container(color: Colors.green),
                    ),
                    Expanded(
                      flex: 1,
                      child: Container(color: Colors.blue),
                    ),
                  ],
                ),
              ),
              SizedBox(height: 20),
              Container(
                height: 100,
                color: Colors.grey[300],
                child: Row(
                  children: [
                    Container(width: 50, color: Colors.yellow),
                    Expanded(
                      child: Container(color: Colors.orange),
                    ),
                    Container(width: 50, color: Colors.purple),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    ),
  );
}

Test Your Knowledge

Q1
of 3

What does Expanded do when placed inside a Row?

A
Expands the child to fill all available vertical space
B
Expands the child to fill all available horizontal space
C
Expands the child to fill all available space in both directions
D
Shrinks the child to its minimum size
Q2
of 3

What is the default `flex` value of Expanded?

A
0
B
1
C
2
D
It has no default; you must specify it
Q3
of 3

Which widget would you use if you want a child to take available space but also allow it to be smaller than that space?

A
Expanded
B
Flexible with FlexFit.tight
C
Flexible with FlexFit.loose
D
Container with width: double.infinity

Previous

flutter padding

Next

flutter mediaquery

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.