Flutter Tutorial

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

PropertyDoes
width, heightFixed size
paddingSpace inside, between the edge and the child
marginSpace outside, around the box
alignmentWhere the child sits inside the box
colorBackground colour, when you need nothing else
decorationBackground, border, radius, shadow, gradient, image
constraintsMinimum and maximum size
transformRotate, 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 width and height: 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 needUse
Empty space or a fixed sizeSizedBox(width: 16), SizedBox(height: 200, child: ...)
Padding onlyPadding(padding: ..., child: ...)
Background colour onlyColoredBox(color: ..., child: ...)
Decoration onlyDecoratedBox(decoration: ..., child: ...)
Centring onlyCenter(child: ...)
A Material cardCard(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.

Practise in the playground Updated