Flutter provides many layout widgets that make building user interfaces easy, powerful, and highly flexible. One such widget is the Stack. As the name suggests, Stack allows developers to place widgets on top of each other, just like stacking objects in the real world.
While widgets like Row and Column help in creating horizontal and vertical arrangements, Stack goes a step further by enabling overlapping layouts. This opens up creative design possibilities, such as creating profile pictures with badges, floating action buttons over content, or custom overlays for banners.
In this deep dive, we will explore the Stack widget in detail, covering its purpose, properties, examples, use cases, and best practices.
Introduction to Stack
The Stack widget is a layout widget in Flutter that allows multiple widgets to be placed on top of each other in the same parent space.
- Think of it as a stack of papers or cards: the first child is placed at the bottom, and subsequent children are placed above it.
- The order of children in the
childrenlist determines their z-index (stacking order).
Why Use Stack?
You should use Stack when you want overlapping layouts. Some situations where Stack is useful:
- Overlays → Displaying text or buttons over an image.
- Floating buttons → Placing a button over a list or screen content.
- Custom banners → Adding “sale” or “discount” labels on top of product cards.
- Profile UI → Showing a user’s avatar with an edit button on top.
- Loading indicators → Placing a spinner on top of the screen while content loads.
Without Stack, achieving these designs would be complex and involve unnecessary nesting.
Basic Syntax of Stack
The Stack widget takes a list of children.
Stack(
children: <Widget>[
Widget1(),
Widget2(),
Widget3(),
],
)
- The first widget becomes the bottom layer.
- Each subsequent widget is placed on top of the previous one.
Example: Simple Stack
Stack(
children: [
Container(
width: 200,
height: 200,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.red,
),
],
)
Result:
- A blue square at the bottom.
- A red square placed above it.
The Role of Alignment in Stack
By default, all children in Stack are positioned at the top-left corner. However, you can control their positioning using the alignment property.
Example
Stack(
alignment: Alignment.center,
children: [
Container(width: 200, height: 200, color: Colors.green),
Container(width: 100, height: 100, color: Colors.orange),
],
)
Here, the orange container is centered over the green container.
Positioned Widget: Precise Control
Stack becomes even more powerful when combined with the Positioned widget. This allows you to define the exact position of a child inside the Stack using properties like top, left, right, and bottom.
Example
Stack(
children: [
Container(width: 200, height: 200, color: Colors.grey),
Positioned(
bottom: 10,
right: 10,
child: Text("Overlay Text"),
),
],
)
Result: The text appears at the bottom-right corner of the container.
Real-World Example: Profile Picture with Edit Button
A very common design in apps is to show a profile picture with a small edit button overlay.
Stack(
children: [
CircleAvatar(
radius: 50,
backgroundImage: AssetImage("assets/profile.jpg"),
),
Positioned(
bottom: 0,
right: 0,
child: CircleAvatar(
radius: 15,
backgroundColor: Colors.white,
child: Icon(Icons.edit, size: 18),
),
),
],
)
- The large CircleAvatar is the profile picture.
- The smaller CircleAvatar with the edit button is positioned on top, at the bottom-right corner.
Properties of Stack
1. alignment
Controls how non-positioned children are aligned. Options include:
Alignment.topLeftAlignment.topRightAlignment.centerAlignment.bottomCenter
2. fit
Controls how non-positioned children are sized. Options:
StackFit.loose(default) → Children keep their natural size.StackFit.expand→ Children expand to fill the stack.
3. clipBehavior
Defines how children overflowing the stack are clipped. Options:
Clip.none(default) → No clipping.Clip.hardEdge→ Clips the overflowing area.Clip.antiAlias→ Smooth clipping with anti-aliasing.
Use Cases of Stack
1. Overlays on Images
You can display text, icons, or buttons on top of images.
2. Floating Buttons
Useful for placing floating action buttons over the UI.
3. Custom Badges
Adding discount or notification badges on top of elements.
4. Complex Layouts
Combining multiple layers for creative UIs such as dashboards and cards.
Example: Banner with Sale Badge
Stack(
children: [
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/product.jpg"),
fit: BoxFit.cover,
),
),
),
Positioned(
top: 10,
left: 10,
child: Container(
color: Colors.red,
padding: EdgeInsets.all(5),
child: Text("SALE", style: TextStyle(color: Colors.white)),
),
),
],
)
Result: A product image with a SALE badge at the top-left corner.
Stack vs Column vs Row
| Feature | Stack | Column | Row |
|---|---|---|---|
| Layout Direction | Overlapping layers | Vertical alignment | Horizontal alignment |
| Children Placement | On top of each other | One below the other | Side by side |
| Use Case | Overlays, badges, floating UI | Forms, lists, text blocks | Toolbars, buttons groups |
Handling Overflow in Stack
If widgets exceed the size of the parent container, overflow can occur. Solutions:
- Use
clipBehaviorto clip overflowing parts. - Wrap Stack with SingleChildScrollView if scrollable content is needed.
- Make use of Flexible or Expanded for dynamic sizing.
Best Practices for Using Stack
- Use Positioned only when necessary for precise layouts.
- Keep the number of children limited to avoid performance issues.
- Combine Stack with other layouts for cleaner designs.
- Always test on different screen sizes to prevent overflow.
- Use Stack for decorative or overlay purposes, not as a replacement for standard layouts.
Advanced Examples of Stack
1. Loading Overlay
Stack(
children: [
Container(color: Colors.white), // Main content
Center(child: CircularProgressIndicator()), // Overlay loader
],
)
2. Chat Message with Timestamp
Stack(
children: [
Container(
padding: EdgeInsets.all(15),
color: Colors.blue[100],
child: Text("Hello! How are you?"),
),
Positioned(
bottom: 5,
right: 5,
child: Text("10:30 AM", style: TextStyle(fontSize: 10)),
),
],
)
Performance of Stack
- Stack itself is lightweight.
- Complexity comes from the number of children and their rendering.
- Avoid placing too many heavy widgets inside Stack.
- Prefer using Stack for small overlays rather than entire screens.
Common Mistakes with Stack
- Using Stack for layouts that could be achieved with Row or Column.
- Forgetting about alignment, leading to unexpected positions.
- Adding too many children and causing performance lag.
- Ignoring clipping, which may cause UI issues.
Leave a Reply