Flutter Layout Tips: Mastering Stack and Positioned for Creative UIs

19 Jan 2026

9K

35K

Flutter Layout Tips: Mastering Stack and Positioned for Creative UIs

Introduction

Flutter's rich set of layout widgets provides immense flexibility for building beautiful and functional user interfaces. Among the most powerful tools for creating layered, overlapping, or precisely placed elements are the Stack and Positioned widgets. This article delves into how these two widgets work in tandem to unlock a new level of creativity in your Flutter UIs.

Understanding the Stack Widget

The Stack widget in Flutter is designed to layer multiple widgets on top of one another, much like a stack of papers. The first child in the Stack's children list is drawn at the bottom, and subsequent children are drawn on top of the previous ones. By default, all children of a Stack are aligned to the top-left corner.

You can control the default alignment of non-Positioned children using the alignment property of the Stack.

Basic Stack Example


import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Basic Stack Example')),
        body: Center(
          child: Stack(
            alignment: Alignment.center, // Aligns children to the center
            children: [
              Container(
                width: 200,
                height: 200,
                color: Colors.blue,
              ),
              Container(
                width: 150,
                height: 150,
                color: Colors.red,
              ),
              Container(
                width: 100,
                height: 100,
                color: Colors.green,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

In this example, the blue container is at the bottom, followed by red, and then green, all centered within the Stack due to the alignment property.

Leveraging the Positioned Widget

While Stack allows layering, Positioned is the key to precisely placing widgets within that Stack. A Positioned widget must be a direct child of a Stack (or an ancestor that resolves to a Stack, but typically direct). It takes properties like top, bottom, left, right, width, and height to specify its exact location and size relative to the Stack's boundaries.

When a child of a Stack is wrapped in a Positioned widget, its position is no longer affected by the Stack's alignment property. Instead, it relies entirely on the Positioned widget's properties.

Positioned Example


import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Stack and Positioned Example')),
        body: Center(
          child: Container(
            width: 300,
            height: 300,
            color: Colors.grey[200],
            child: Stack(
              children: [
                // Background element
                Positioned.fill(
                  child: Image.network(
                    'https://via.placeholder.com/300x300/CCCCCC/FFFFFF?text=Background',
                    fit: BoxFit.cover,
                  ),
                ),
                // Top-left text
                Positioned(
                  top: 20,
                  left: 20,
                  child: Text(
                    'Top Left',
                    style: TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold),
                  ),
                ),
                // Bottom-right button
                Positioned(
                  bottom: 20,
                  right: 20,
                  child: ElevatedButton(
                    onPressed: () {},
                    child: Text('Action'),
                  ),
                ),
                // Centered icon with custom size
                Positioned(
                  top: 100,
                  left: 100,
                  width: 100,
                  height: 100,
                  child: Icon(
                    Icons.star,
                    color: Colors.yellow,
                    size: 80,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Notice Positioned.fill which is a convenient constructor to make a child fill the entire Stack, often used for background images or overlays.

Creative UI Use Cases and Tips

The combination of Stack and Positioned opens up a world of possibilities for intricate and visually appealing UIs:

1. Overlapping Profile Pictures and Badges

A common pattern is a user's profile picture with a small status indicator or badge overlapping it.


Stack(
  children: [
    CircleAvatar(
      radius: 40,
      backgroundImage: NetworkImage('https://via.placeholder.com/150'),
    ),
    Positioned(
      bottom: 0,
      right: 0,
      child: Container(
        width: 20,
        height: 20,
        decoration: BoxDecoration(
          color: Colors.green,
          shape: BoxShape.circle,
          border: Border.all(color: Colors.white, width: 2),
        ),
      ),
    ),
  ],
)

2. Text Over Images

Placing text or other widgets directly on top of an image for captions, titles, or interactive elements.


SizedBox(
  width: double.infinity,
  height: 200,
  child: Stack(
    children: [
      Image.network(
        'https://via.placeholder.com/600x200/FF0000/FFFFFF?text=Beautiful+Landscape',
        fit: BoxFit.cover,
        width: double.infinity,
      ),
      Positioned(
        bottom: 10,
        left: 10,
        child: Text(
          'Sunset View',
          style: TextStyle(
            color: Colors.white,
            fontSize: 28,
            fontWeight: FontWeight.bold,
            shadows: [
              Shadow(
                blurRadius: 5.0,
                color: Colors.black.withOpacity(0.5),
                offset: Offset(2.0, 2.0),
              ),
            ],
          ),
        ),
      ),
    ],
  ),
)

3. Custom Overlays and Modals

For custom loading indicators, tooltips, or pop-up messages that need to float above the primary content.


Stack(
  children: [
    // Main content of your screen
    ListView(
      children: List.generate(20, (index) => ListTile(title: Text('Item $index'))),
    ),
    // Overlay (e.g., loading spinner)
    Positioned.fill(
      child: Container(
        color: Colors.black.withOpacity(0.5),
        child: Center(
          child: CircularProgressIndicator(),
        ),
      ),
    ),
  ],
)

4. Floating Action Buttons with Custom Placement

While Scaffold provides a floatingActionButton, Stack and Positioned can be used for more complex custom floating elements, or multiple floating elements.


Stack(
  children: [
    // Your main content
    Container(color: Colors.white),
    Positioned(
      bottom: 20,
      right: 20,
      child: FloatingActionButton(
        onPressed: () {},
        child: Icon(Icons.add),
      ),
    ),
    Positioned(
      bottom: 90, // Position another button above the first
      right: 20,
      child: FloatingActionButton(
        mini: true,
        onPressed: () {},
        child: Icon(Icons.share),
      ),
    ),
  ],
)

Advanced Tips and Considerations

Combine with Align Widget

For children that don't need pixel-perfect positioning but rather alignment to an edge or center, using an Align widget as a child of Stack can be simpler than Positioned. Align respects the Stack's size and places its child according to its alignment property.


Stack(
  children: [
    Container(width: 200, height: 200, color: Colors.blueGrey),
    Align(
      alignment: Alignment.bottomLeft,
      child: Text('Bottom Left', style: TextStyle(color: Colors.white)),
    ),
    Align(
      alignment: Alignment.topRight,
      child: Icon(Icons.info, color: Colors.yellow),
    ),
  ],
)

Responsiveness with MediaQuery

When using Positioned, especially with fixed pixel values, be mindful of different screen sizes. For responsive designs, consider using percentages of screen width/height obtained via MediaQuery.of(context).size.


// Inside a Widget's build method
double screenWidth = MediaQuery.of(context).size.width;
Stack(
  children: [
    // ...
    Positioned(
      left: screenWidth * 0.1, // 10% from left
      top: screenWidth * 0.05, // 5% from top (relative to width for aspect ratio)
      child: Container(
        width: screenWidth * 0.3,
        height: 50,
        color: Colors.purple,
      ),
    ),
  ],
)

Performance

While Stack is generally efficient, avoid overly deep or complex widget trees within its children, especially if many are being constantly rebuilt. For static overlays or a few dynamic elements, performance impact is usually negligible.

Conclusion

The Stack and Positioned widgets are indispensable tools in a Flutter developer's arsenal for crafting sophisticated and visually appealing UIs. By understanding how to layer widgets with Stack and precisely control their placement with Positioned, you can move beyond conventional layouts and bring your most creative design ideas to life. Experiment with these widgets to discover the endless possibilities they offer for unique and engaging user experiences.

Related Articles

Aug 24, 2026

Building with Vue.js: Deployment and Maintenance Guide

Learn how to deploy and maintain Vue.js applications effectively. Discover best practices for optimized builds, server configuration, and long-term stability.

Aug 23, 2026

React Tutorial: Practical Code Examples for Developers

Master React development with practical code examples. Learn core concepts like components, state, and hooks to build efficient, scalable web applications.

Aug 23, 2026

Essential Laravel Best Practices: Common Mistakes to Avoid

Learn how to write cleaner, more secure, and efficient code by avoiding these common Laravel development mistakes. Improve your application architecture today.