Skip to content

Intermediate · Layouts · topic 20 of 50 · 35 min

Understanding constraints and fixing overflow

Explanation

Flutter layout follows one rule: constraints go down, sizes go up, and the parent sets the position. A parent tells each child the minimum and maximum width and height it may have; the child picks a size within them. Tight constraints force an exact size; loose ones set only a maximum. Most layout errors, such as "RenderFlex overflowed by N pixels" and unbounded height, come from breaking this rule, and are fixed with Expanded, Flexible, scrolling or a bounded size.

The rule

Flutter's official documentation sums up layout in one sentence: "Constraints go down. Sizes go up. Parent sets position." Once you understand it, layout errors stop being mysterious.

output
Parent:  "You may be 0 to 360 wide and 0 to 600 tall."   (constraints go DOWN)
Child:   "Then I will be 360 wide and 48 tall."           (size goes UP)
Parent:  "OK, I will place you at the top, 16 from the left."   (parent sets POSITION)
Every widget has this conversation with its parent during layout.

Constraints are four numbers: minimum and maximum width, minimum and maximum height. A child can never choose a size outside them, and a child does not decide its own position; its parent does.

Tight and loose constraints

KindMeaningExample
Tightmin = max: the child must be exactly that sizeThe screen gives the root widget the full screen size
Loosemin = 0: the child may be any size up to the maxCenter passes loose constraints, so its child can be small
Unboundedmax = infinity in one directionA ListView inside a Column, or the main axis of a Row/Column for its children

This explains a classic surprise: Container(width: 100, height: 100) placed directly as the app's home fills the whole screen. The screen gives tight constraints (exactly full size), so the Container cannot be 100 x 100. Wrap it in Center, which loosens the constraints, and it becomes 100 x 100.

The yellow and black stripes: overflow

output
A RenderFlex overflowed by 87 pixels on the right.
The relevant error-causing widget was: Row
In debug builds, Flutter draws yellow-and-black stripes where content does not fit.

A Row gives its non-flexible children unbounded width (they may be as wide as they like), then adds them up. If a long Text wants 450 pixels on a 360-pixel phone, the Row overflows. Fixes:

  • Wrap the long child in Expanded or Flexible so it gets only the remaining space, with overflow: TextOverflow.ellipsis or maxLines.
  • Allow wrapping onto new lines with the Wrap widget instead of Row (good for chips and tags).
  • Make the content scrollable with SingleChildScrollView when it is genuinely longer than the screen.
  • Reduce sizes or use responsive layouts for small screens (module 10).

Unbounded height: ListView inside Column

dart
Column(
  children: [
    const Text('Recent orders'),
    ListView(children: orderTiles),     // ERROR: Vertical viewport was given unbounded height
  ],
)

Column(
  children: [
    const Text('Recent orders'),
    Expanded(child: ListView(children: orderTiles)),   // FIX: give the list the remaining height
  ],
)
A Column gives children unbounded height; a ListView wants to be as tall as possible. Infinity is not a size.

Another option is shrinkWrap: true on the ListView, which makes it only as tall as its items. It works, but it builds all items at once, so avoid it for long lists; prefer Expanded or making the whole screen one scrollable list (module 6).

Think of it like this: Constraints are like a parent giving a child a budget: "spend between 0 and 500 rupees". The child decides how much to spend within that budget and reports back; the parent decides where the purchase goes in the house. Overflow is the child trying to buy something that costs 600.

Debugging layouts

Open Flutter DevTools' widget inspector and turn on "Show guidelines" or use the Layout Explorer: it shows each widget's constraints and size. Reading the first lines of the error in the console (which widget, which direction, how many pixels) usually points straight at the fix.

Common mistakes

  • Adding fixed widths everywhere to "fix" overflow, which breaks on smaller phones.
  • Putting a ListView or GridView directly inside a Column without Expanded.
  • Using shrinkWrap: true on long lists, hurting performance.
  • Ignoring the overflow stripes in debug because "it looks fine on my phone"; other phones are narrower or use larger fonts.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Understanding constraints and fixing overflow · 1/6

Constraints ↓ Sizes ↑ Parent positions

Flutter layout follows one rule: constraints go down, sizes go up, the parent sets position.

Prefer a video by a teacher? Find free videos on “flutter constraints go down sizes go up overflow error unbounded height fix” on YouTube ↗

In real life: Fixing a broken order screen

A food app's order screen crashed with "Vertical viewport was given unbounded height" and showed stripes on small phones. The developer wrapped the item list in Expanded so it takes the space between the header and the Pay button, and wrapped the long restaurant name in Flexible with an ellipsis. The screen now works from 5-inch budget phones to tablets.

dart
Column(
  children: [
    Row(
      children: [
        const Flexible(child: Text('Sri Krishna Sweets and Restaurant, MG Road', overflow: TextOverflow.ellipsis)),
        const SizedBox(width: 8),
        Text('Open', style: TextStyle(color: Colors.green.shade700)),
      ],
    ),
    Expanded(child: ListView(children: const [ListTile(title: Text('Mysore pak x 2'))])),
    FilledButton(onPressed: () {}, child: const Text('Pay Rs 340')),
  ],
)
Flexible for long text in a Row; Expanded for a list in a Column.

Practice (0/3 done)

Task 1 · Question

You see "A RenderFlex overflowed by 40 pixels on the right" for a Row with a long Text. Best fix?

Task 2 · Question

Why does Container(width: 100, height: 100) as the app's home fill the whole screen?

Task 3 · Practice

Create three broken layouts on purpose: (1) a Row with a very long Text, (2) a ListView directly inside a Column, (3) a Column taller than the screen. Read each error message, then fix them with Flexible/Expanded, Expanded around the ListView, and SingleChildScrollView. Write one sentence per fix explaining the constraint rule behind it.

Quick quiz

Question 1

1.Who decides a widget's position?

Question 2

2.What does "tight constraints" mean?

Question 3

3.What is the problem with shrinkWrap: true on a long ListView?

Question 4

4.Which widget lets chips flow onto the next line instead of overflowing?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Who decides a widget's position?

Answer: Its parent

Parent sets position.

What does "tight constraints" mean?

Answer: min equals max, so the size is forced

The child must be exactly that size.

What is the problem with shrinkWrap: true on a long ListView?

Answer: It builds all items at once, hurting performance

Prefer Expanded or a single scrollable.

Which widget lets chips flow onto the next line instead of overflowing?

Answer: Wrap

Wrap moves children to new lines.

When is the plain ListView(children: [...]) a good choice?Related

Answer: For short, fixed lists

All children are built at once.

From Lists with ListView

Which property lets children draw outside the Stack's bounds?Related

Answer: clipBehavior: Clip.none

The default clips.

From Stack, Positioned and Align

What matters most in a take-home assignment?Related

Answer: A working, clean, tested app with handled states and a clear README

Quality over quantity.

From Interview questions: Flutter

What is the difference between Expanded and Flexible?Related

Answer: Expanded must fill its share; Flexible may be smaller

Expanded is Flexible with a tight fit.

From Container, Padding, SizedBox, Expanded and Flexible

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 1 more topic in “Layouts” before its exam: Images, icons, fonts and themes.
  2. Module 5 exam: Layouts · 13 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Lists, navigation and forms. 50 topics left in the course before the final exam.

← Previous: Stack, Positioned and Align