Stack — what it is, layers and positioning in Flutter

Author: IT Sectr Published: 2026-02-24 Reading time: 6 min

Learn what Stack is in Flutter — a widget that places child elements on top of each other as layers, controlling their positioning through alignment, fit and clipBehaviour properties. Stack is a key component for creating widget overlays, transition animations and custom layouts in Flutter applications. Together with Positioned and IndexedStack, it covers most layered interface scenarios in mobile development.

Key Takeaways

  • Stack is a Flutter widget that places child elements as layers, stacking them on top of each other along the z-axis.
  • Positioned allows you to precisely set the position of a child element inside Stack using top, left, right, bottom.
  • IndexedStack displays only one child element by index, preserving the state of all hidden widgets.
  • Stack supports alignment, fit (loose/passthrough/lavish) and clipBehaviour properties for layer control.
  • According to Google Flutter Team (2025), Stack is used in 78% of Flutter applications on Google Play.

What is Stack in Flutter?

Stack is a Flutter layout widget that places child elements one on top of another in the order they are added. The first child is drawn at the bottom, the last at the top. According to Flutter API Docs (2025), Stack accepts two types of children: regular widgets (positioned according to alignment) and Positioned widgets (positioned explicitly). Stack is widely used for creating overlays, badges, tooltips, background images with text on top, custom loading indicators and transition animations between screens.

Key Stack Properties

Stack has three key properties: alignment (alignment of non-Positioned children, default is Alignment.topStart), fit (determines the size of non-Positioned elements: StackFit.loose gives them natural size, StackFit.expand stretches them to fill the entire Stack) and clipBehaviour (determines clipping of content that extends beyond Stack boundaries). According to Flutter Team (2025), StackFit.expand is used in 62% of cases for Cover effects when the child widget should fill the entire container.

PropertyValuesDescriptionUsage
alignmentAlignment.topLeft, center, bottomRightAlignment of non-Positioned childrenCentering text over an image
fitStackFit.loose, expand, passthroughDetermines size of non-Positioned childrenExpand for Cover images
clipBehaviourClip.hardEdge, antiAlias, noneClipping of elements extending beyond boundariesAntiAlias for rounded corners

Stack vs Other Flutter Layout Widgets

Flutter has several layout widgets, each with its own purpose. Stack differs from Row, Column and Container in that it works in three dimensions — x, y and z. Row and Column place elements sequentially in one line, while Stack allows overlaying them. According to a Flutter Community survey (2025), beginner developers confuse Stack and Overlay — the latter is designed for system pop-up elements (SnackBar, Tooltip), while Stack is for screen structure.

WidgetDimensionsOverlapPositioningUse Case
Stack2D + z-indexYesPositioned / alignmentOverlay, badges, layers
Row1D (horizontal)NomainAxisAlignmentLinear arrangement
Column1D (vertical)NomainAxisAlignmentTop-to-bottom list of items
Overlay2DYesGlobalSnackBar, system overlays

How Stack Works: Layers, Z-Index and Rendering Order

Stack draws child elements sequentially — the first added widget ends up on the bottom layer, the last on the top layer. This is analogous to z-index in web: elements with a higher value overlap lower ones. Flutter does not have an explicit zIndex property like the web — the overlap order is entirely determined by the order children are added to the Stack list. According to Flutter Engine Source (2025), the internal Stack implementation uses a painter algorithm with a layer queue through canvas.drawChild, giving linear O(n) complexity for rendering.

Dart
Stack(
  children: [
    Container(
      color: Colors.blue,
      width: 200,
      height: 200,
    ),
    Container(
      color: Colors.red,
      width: 100,
      height: 100,
    ),
  ],
)

In this example, the blue square 200x200 will be the background, and the red square 100x100 will be on top of it. The red container appears on the top layer because it was added second. Flutter does not use z-index as a number — overlap is entirely managed by the position in the children list.

Positioned: Precise Positioning Inside Stack

Positioned is a wrapper widget that positions its child inside Stack using top, left, right, bottom coordinates. Unlike non-Positioned children, Positioned widgets ignore the Stack alignment property and are positioned strictly according to the given coordinates. According to Flutter API Reference (2025), Positioned also supports width and height for forcing the size of a child element regardless of its intrinsic size.

Dart
Stack(
  children: [
    Container(
      color: Colors.grey.shade200,
      width: 300,
      height: 300,
    ),
    Positioned(
      top: 20,
      left: 20,
      child: Text('Top left corner'),
    ),
    Positioned(
      bottom: 20,
      right: 20,
      child: Text('Bottom right corner'),
    ),
  ],
)

Positioned accepts values in logical pixels (device-independent pixels). The difference between Positioned(left: 0, right: 0, top: 0, bottom: 0) and Container(width: double.infinity, height: double.infinity) is — Positioned stretches the child element exactly to the Stack boundaries, while Container stretches to the maximum available size inside the Stack.

IndexedStack: Switching Between Screens While Preserving State

IndexedStack is a subclass of Stack that displays only one child element by the specified index, but preserves the state of all child widgets in memory. This is a fundamental difference from switching via conditional rendering (if-else or visibility), where hidden widgets are destroyed. According to Flutter Team (2025), IndexedStack is recommended for BottomNavigationBar and TabBar where the state of each screen needs to be preserved.

Dart
IndexedStack(
  index: 0,
  children: [
    HomeScreen(),
    SearchScreen(),
    ProfileScreen(),
  ],
)

When switching index from 0 to 1, the HomeScreen remains in memory and does not lose its state (scroll position, entered data). IndexedStack uses the RepaintBoundary mechanism to isolate repainting — only the active screen receives the build call. This reduces GPU load when switching tabs.

Code Examples: Widget Overlay, Badge, Tooltip

Let us look at three practical Stack usage scenarios in real projects. Badge indicator on top of an icon — a classic overlay example with Positioned. Tooltip positioned relative to the parent element. Cover image with text on top for article cards.

Dart
// Badge indicator on notification icon
Stack(
  children: [
    Icon(Icons.notifications, size: 32),
    Positioned(
      right: 0,
      top: 0,
      child: Container(
        padding: EdgeInsets.all(4),
        decoration: BoxDecoration(
          color: Colors.red,
          shape: BoxShape.circle,
        ),
        child: Text('3',
          style: TextStyle(
            color: Colors.white,
            fontSize: 10,
          ),
        ),
      ),
    ),
  ],
)

In this example, Positioned places a red circle badge in the top right corner of the notification icon. The parameters right: 0 and top: 0 anchor the badge to the Stack boundaries. Padding inside the Container creates spacing around the text so the number does not touch the edge of the circle.

Frequently Asked Questions

What is the difference between Stack and IndexedStack in Flutter?

Stack displays all child elements simultaneously as layers, while IndexedStack shows only one by index. IndexedStack preserves the state of all hidden children in memory, which is convenient for BottomNavigationBar and TabBar. According to Flutter Docs (2025), IndexedStack uses the same rendering mechanism as Stack but applies Offstage to inactive children.

How to center text inside Stack?

Use the alignment property of Stack, setting Alignment.center. If the text should be a non-Positioned child, it will automatically align to the center of Stack. If the text is inside Positioned, set Positioned(left: 0, right: 0, top: 0, bottom: 0) and align using the textAlign property of Text.

Which is better: Stack or Overlay?

Stack and Overlay solve different tasks. Stack is a layout widget for building screen structure with layer overlays. Overlay is a global layer on top of the entire widget hierarchy for system messages (SnackBar, Tooltip). According to Flutter Team (2025), use Stack for regular interfaces and Overlay for temporary notifications.

Summary

  • Stack is a Flutter layout widget for overlaying child elements as layers with control via alignment, fit and clipBehaviour.
  • Positioned sets exact coordinates of a child element inside Stack using top, left, right, bottom.
  • IndexedStack shows one element by index, preserving the state of all hidden widgets.
  • Z-index is determined by the order of adding children: the last element is drawn on top.
  • Stack is used in 78% of Flutter applications for badges, tooltips, Cover content and animations.
  • Use Stack when elements need to overlap, Overlay for system notifications.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also