Dart Tutorial

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 #

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 by Santosh Adhikari