Flutter Beginner Lesson 14 of 135 3 min read
Container, BoxDecoration and SizedBox in Flutter
Learn the Container widget in Flutter: size, padding, margin, colour, borders, rounded corners, shadows and gradients with BoxDecoration.
On this page
Container is a convenience widget that combines sizing, spacing, alignment and decoration. It is what you reach for to draw a box.
A decorated box
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
backgroundColor: const Color(0xFFF2F4F8),
body: Center(
child: Container(
width: 260,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.black12),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 12,
offset: Offset(0, 6),
),
],
),
child: const Text('A card built from a Container'),
),
),
),
),
);
}
The main properties
| Property | Does |
|---|---|
width, height | Fixed size |
padding | Space inside, between the edge and the child |
margin | Space outside, around the box |
alignment | Where the child sits inside the box |
color | Background colour, when you need nothing else |
decoration | Background, border, radius, shadow, gradient, image |
constraints | Minimum and maximum size |
transform | Rotate, scale or move |
EdgeInsets
const EdgeInsets.all(16) // every side
const EdgeInsets.symmetric(horizontal: 24, vertical: 8)
const EdgeInsets.only(left: 12, top: 4)
const EdgeInsets.fromLTRB(16, 8, 16, 24) // left, top, right, bottom
color or decoration, never both
Setting both is an error. When you use decoration, the colour goes inside it.
// Wrong: throws an assertion error.
Container(color: Colors.blue, decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)))
// Right.
Container(
decoration: BoxDecoration(color: Colors.blue, borderRadius: BorderRadius.circular(8)),
)
What BoxDecoration can do
BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
// or: borderRadius: const BorderRadius.vertical(top: Radius.circular(24)),
border: Border.all(color: Colors.indigo, width: 2),
// or: border: const Border(bottom: BorderSide(color: Colors.black12)),
boxShadow: const [
BoxShadow(color: Colors.black26, blurRadius: 8, offset: Offset(0, 4)),
],
gradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Colors.indigo, Colors.purple],
),
shape: BoxShape.rectangle, // or BoxShape.circle
)
When a gradient is set, it is drawn over color. BoxShape.circle cannot be combined with borderRadius.
How a Container decides its size
This confuses everyone at first.
- With a child and no size: it shrinks to fit the child.
- With no child and no size: it grows as large as its parent allows.
- With
widthandheight: it uses them, if the parent permits.
If your container fills the whole screen unexpectedly, it probably has no child, or it has an alignment, which also makes it expand.
Lighter alternatives
Container does many jobs. When you need only one, a simpler widget says what you mean and can be const.
| You need | Use |
|---|---|
| Empty space or a fixed size | SizedBox(width: 16), SizedBox(height: 200, child: ...) |
| Padding only | Padding(padding: ..., child: ...) |
| Background colour only | ColoredBox(color: ..., child: ...) |
| Decoration only | DecoratedBox(decoration: ..., child: ...) |
| Centring only | Center(child: ...) |
| A Material card | Card(child: ...) |
SizedBox is the standard way to add a gap between widgets:
Column(
children: const [
Text('Title'),
SizedBox(height: 8),
Text('Subtitle'),
],
)
Clipping the child
A border radius on the decoration does not clip the child. If an image inside pokes out of the rounded corners, add clipBehavior.
Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(16)),
child: Image.network(url, fit: BoxFit.cover),
)
Try it yourself
Build a gradient “balance card” 180 pixels tall with rounded corners and a soft shadow. Put a small label in the top-left corner and a large amount in the bottom-left, using a Column with mainAxisAlignment: MainAxisAlignment.spaceBetween.