What is SafeArea and when should you use it?
2 min read
Widgets & UI
Wrap content that must stay visible in SafeArea; do not wrap full-bleed backgrounds (images, gradients) — those should extend behind the system UI. SafeArea reads MediaQuery.paddingOf(context) and adds padding on each side that the system UI would otherwise obscure. By default it pads all four sides; you can disable any of them, set a minimum padding, or use maintainBottomViewPadding to keep bottom padding even when the keyboard is up.
Code in action
// Standard usage — wrap content that must not be obscured
Scaffold(
body: SafeArea(
child: Column(
children: const [
Text('Header'),
Expanded(child: MyList()),
],
),
),
);
// Selective insets — content goes edge-to-edge horizontally
SafeArea(
top: true,
bottom: true,
left: false, // allow content to touch left edge
right: false,
child: ...,
);
// Minimum padding even when there's no intrusion
SafeArea(
minimum: const EdgeInsets.all(16),
child: ...,
);
When to use it (and when not)
| Situation | SafeArea? |
|---|---|
| Buttons, text, important controls | ✅ Yes |
| Scrollable list (so first/last item isn't under bars) | ✅ Yes (or use SafeArea only around fixed parts) |
| Full-bleed background image / gradient | ❌ No — let it extend under the system UI |
Inside a Scaffold body — top is already handled by AppBar | Often only bottom: true is needed |
| Modal bottom sheet content | ❌ The sheet handles its own safe insets |
Inside Scaffold but using extendBody: true | ✅ Wrap content in SafeArea to compensate |
Common mistakes to avoid
// ❌ Wrapping everything in SafeArea — including the full-screen background
Stack(children: [
SafeArea(child: BackgroundImage()), // ❌ leaves ugly bands under notch / home indicator
SafeArea(child: HeroContent()),
]);
// ✅ Let background be full-bleed; only inset the content
Stack(children: [
BackgroundImage(),
SafeArea(child: HeroContent()),
]);
// ❌ Double-padding — Scaffold + SafeArea both compensating
Scaffold(
appBar: AppBar(...), // AppBar already pads for status bar
body: SafeArea(top: true, child: ...), // doubles the top inset
);
// ✅ When AppBar is present, you usually only need bottom safe area
// ❌ SafeArea inside an already-inset modal sheet
showModalBottomSheet(
builder: (ctx) => SafeArea(child: ...), // sheet already insets bottom
);
// ❌ Not testing on devices with notches/home indicators
// Use the DevTools simulators or Pixel 6/iPhone 14 Pro device previews
Interview follow-ups
-
What's the difference between
SafeAreaandMediaQuery.padding?MediaQuery.paddingis the raw inset data Flutter exposes.SafeAreais a widget that reads that data and applies it as padding. You can replicateSafeAreamanually if you need finer control. -
Why might you set
top: falseon a SafeArea? Because something above already handles the top inset — typically anAppBarorSliverAppBarinside aScaffold. Double-insetting leaves an ugly gap. -
How does SafeArea interact with the keyboard? By default Scaffold resizes when the keyboard appears (
resizeToAvoidBottomInset: true) and SafeArea's bottom inset shrinks accordingly. UsemaintainBottomViewPadding: trueif you specifically need the bottom padding to stay the same. -
What's
extendBody/extendBodyBehindAppBarand how does SafeArea fit in? These let the Scaffold body extend behind the bottom bar / app bar (great for transparent app bars). Once you turn them on, the body no longer auto-insets — wrap the content inSafeAreato put it back where it belongs.
How helpful was this content?
Please sign in to rate this article.