Flutter Lesson 13 of 83 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.