Skip to content

Containers & Padding

In CSS every HTML element is a box with padding, margin, border, width, and height. Flutter does not have a CSS box model — instead it has dedicated widgets for each concern. This sounds verbose at first, but it makes the layout intent explicit and composable.

The three widgets you will reach for most often are Container (all-in-one box), Padding (spacing only), and SizedBox (fixed dimensions or gaps).

CSS propertyFlutter widget / property
padding: 16pxPadding(padding: EdgeInsets.all(16))
padding: 8px 16pxEdgeInsets.symmetric(vertical: 8, horizontal: 16)
padding: 4px 8px 12px 16pxEdgeInsets.only(top: 4, right: 8, bottom: 12, left: 16)
margin: 8pxWrap parent in Padding, or use Container(margin: ...)
width: 200px; height: 100pxSizedBox(width: 200, height: 100)
width: 100%SizedBox(width: double.infinity)
background-color, border-radius, box-shadow, borderContainer(decoration: BoxDecoration(...))
width: 200px; background: blue; border-radius: 8pxContainer(width: 200, decoration: BoxDecoration(color: Colors.blue, borderRadius: ...))

Padding — use when you only need spacing around a child. It is lighter than Container because it has no painting cost.

SizedBox — use when you need a fixed size, or as a gap between widgets (SizedBox(height: 16) is idiomatic vertical spacing).

Container — use when you need multiple visual properties at once: color, padding, margin, border, border-radius, or shadow. Do not use Container just for padding — use Padding instead.

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: const Color(0xFFF5F5F5),
        appBar: AppBar(title: const Text('Containers & Padding')),
        body: SingleChildScrollView(
          padding: const EdgeInsets.all(16),   // Padding on ScrollView
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            spacing: 16,
            children: [
              // ------- Padding only -------
              const _Label('Padding — all sides 16px'),
              Padding(
                padding: const EdgeInsets.all(16),
                child: Container(color: Colors.blue[100],
                    child: const Text('Content with padding')),
              ),

              // ------- SizedBox as gap + fixed size -------
              const _Label('SizedBox — fixed 200x60'),
              Center(
                child: SizedBox(
                  width: 200, height: 60,
                  child: Container(color: Colors.green[200],
                      alignment: Alignment.center,
                      child: const Text('200 x 60')),
                ),
              ),

              // ------- Container — full box model -------
              const _Label('Container — color + border-radius + shadow'),
              Container(
                padding: const EdgeInsets.all(20),
                margin: const EdgeInsets.symmetric(horizontal: 8),
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(16),
                  boxShadow: [
                    BoxShadow(color: Colors.black.withOpacity(0.08),
                        blurRadius: 10, offset: const Offset(0, 4)),
                  ],
                ),
                child: const Text('This card uses BoxDecoration'),
              ),

              // ------- EdgeInsets.only -------
              const _Label('EdgeInsets.only — asymmetric padding'),
              Container(
                color: Colors.orange[100],
                padding: const EdgeInsets.only(
                    top: 4, right: 8, bottom: 12, left: 24),
                child: const Text('top:4 right:8 bottom:12 left:24'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _Label extends StatelessWidget {
  final String text;
  const _Label(this.text);

  @override
  Widget build(BuildContext context) => Text(text,
      style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 12,
          color: Colors.grey));
}
Which widget should you use when you only need to add padding around a child, with no other visual styling?
What is the Flutter equivalent of `width: 100%` in CSS?
What happens if you set both `color` and `decoration` on the same `Container`?
What is the idiomatic Flutter way to add a 16-pixel gap between two Column children?