Intermediate · Layouts · topic 20 of 50 · 35 min
Understanding constraints and fixing overflow
Explanation
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.
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)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
| Kind | Meaning | Example |
|---|---|---|
| Tight | min = max: the child must be exactly that size | The screen gives the root widget the full screen size |
| Loose | min = 0: the child may be any size up to the max | Center passes loose constraints, so its child can be small |
| Unbounded | max = infinity in one direction | A 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
A RenderFlex overflowed by 87 pixels on the right.
The relevant error-causing widget was: RowA 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
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
],
)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).
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
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.
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')),
],
)Practice (0/3 done)
You see "A RenderFlex overflowed by 40 pixels on the right" for a Row with a long Text. Best fix?
Why does Container(width: 100, height: 100) as the app's home fill the whole screen?
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
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Images, icons, fonts and themesLayouts · same module
- Lists with ListViewLists, navigation and forms
- Interview questions: FlutterFlutter careers and interviews
- CREATE TABLE and constraintsSQL and Databases · Databases and the relational model
- The box modelFrontend Web Development · CSS basics
- Responsive design and media queriesFrontend Web Development · CSS layout and responsive design
Questions people ask about this
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
Which property lets children draw outside the Stack's bounds?Related
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.
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.
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 more topic in “Layouts” before its exam: Images, icons, fonts and themes.
- Module 5 exam: Layouts · 13 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Lists, navigation and forms. 50 topics left in the course before the final exam.