Flexible: what it is, how it works and configuration in mobile development

Author: IT Sectr Published: 2026-07-03 Reading time: 6 min

Flexible is a Flutter widget that controls how a child element occupies available space in a Flex container. Unlike Expanded, Flexible does not force the child to fill the entire allocated area — the child widget can be smaller, and the remaining space stays empty. According to the official Flutter documentation (2026), Flexible is needed in scenarios where flexible space distribution is required without forced stretching: buttons with minimum width, text blocks with natural size, and elements with intrinsic constraints.

Key Takeaways

  • Flexible is a layout widget for flexible space distribution in Row, Column or Flex
  • FlexFit.loose allows the child to be smaller than the allocated space, FlexFit.tight forces it to fill
  • Flexible with loose is suitable for widgets whose size should be determined by content
  • Difference from Expanded: Expanded has no fit parameter and always works as tight
  • Flex factor works the same for Flexible and Expanded — share of free space

What is Flexible

Flexible is a wrapper widget that provides flexible space to a child element in a Flex container. Flexible, like Expanded, participates in distributing free space, but with a key difference: the child of Flexible can take up less space than allocated if its own size is smaller than the available space.

Flexible uses Flutter’s Flex algorithm to calculate available space. First, the framework queries all inflexible children (widgets without Flexible/Expanded) and calculates their intrinsic size. The remaining space is divided among flexible children proportionally to their flex factors. After space allocation, Flexible checks the fit — if it is loose, the child receives a constraint of “no larger than allocated”, allowing it to stay small.

A feature of Flexible: if the child widget has its own minimum sizes (for example, Text with a long string), Flexible allocates the requested space without forced stretching. This makes Flexible indispensable for elements whose size should be determined by content rather than by the container.

In summary: use Flexible when you need to reserve space for an element but not force it to stretch. This preserves the natural sizes of content while maintaining flexible layout distribution.

FlexFit.tight vs FlexFit.loose

FlexFit is an enumeration of two values: tight and loose. The choice of fit determines whether the child widget will be forcibly stretched to the size of the allocated space.

FlexFit.tight: the child element receives tight constraints — the minimum and maximum sizes equal the allocated space. The child must occupy exactly as much space as the Flex algorithm allocated. If the child is smaller — it stretches. If larger — it shrinks. The behavior is identical to Expanded.

FlexFit.loose: the child element receives loose constraints — the minimum size is 0, the maximum equals the allocated space. The child can be any size from 0 to maximum. If the child is small (for example, Text with a short string), it occupies its natural width, and the remaining space stays empty.

In summary: FlexFit.loose is the choice for text blocks and elements with natural size. FlexFit.tight is for strict column layouts where all elements must have the same width or height.

When to use Flexible instead of Expanded

Flexible and Expanded look similar but solve different tasks. Expanded always stretches the child to fill the entire available space. Flexible can leave empty space around the child if the content size is smaller than the allocated share.

Scenario for Flexible: inside a Row there are two buttons. The first — “Buy” (short text), the second — “Add to Cart” (long text). With Expanded, both buttons stretch to equal width, and the short text will have huge padding. With Flexible, each button takes the width of its text, and free space remains between them or at the edges.

Scenario for Expanded: inside a Column there are three cards that should occupy equal height regardless of content. Expanded evenly divides the available height, and each card stretches to the same size. Flexible with loose would not work here — a small card would stay small, breaking the uniform design.

In summary: choose Flexible when content determines element size and empty space around it is acceptable. Choose Expanded when all elements must be the same size regardless of content.

Code examples with Flexible

Example 1 demonstrates basic usage of Flexible with FlexFit.loose in a Row.

dart
Row(
  children: [
    Flexible(
      fit: FlexFit.loose,
      child: Container(
        color: Colors.amber,
        child: const Text('short'),
      ),
    ),
    Flexible(
      fit: FlexFit.loose,
      child: Container(
        color: Colors.cyan,
        child: const Text('long text for demo'),
      ),
    ),
  ],
)

In the example, both Flexible use loose fit. The first container with short text occupies its natural width. The second with long text — its own. Row allocates each half of the available width, but loose fit allows the containers to be smaller, and free space remains empty between them.

Example 2 — comparison of Flexible with Tight and Loose fit in a Column.

dart
Column(
  children: [
    Flexible(
      fit: FlexFit.tight,
      child: const Card(
        child: ListTile(
          title: Text('Tight — stretched full height'),
        ),
      ),
    ),
    const SizedBox(
      height: 8,
    ),
    Flexible(
      fit: FlexFit.loose,
      child: const Card(
        child: ListTile(
          title: Text('Loose — natural height'),
        ),
      ),
    ),
  ],
)

In the Column, the first Flexible (tight) stretches the Card to half of the available height. The second Flexible (loose) — the Card takes height according to its content, and the remaining space stays empty. Visually, you can see how tight forcibly fills the area, while loose preserves a compact size.

In summary: in production code, Flexible with loose is used for form fields, buttons, and text blocks. Flexible with tight is equivalent to Expanded and is used for even distribution.

Common mistakes when using Flexible

Mistake 1: using Flexible outside a Flex container. Like Expanded, Flexible throws a LayoutException if not placed inside Row, Column or Flex. Solution: always check the parent widget chain.

Mistake 2: confusing Flexible and Expanded. Developers often use Expanded when Flexible with loose fit is needed, and vice versa. Result: Expanded stretches an element with short text, creating large empty margins. Solution: if the element size can be smaller than allocated — use Flexible(fit: FlexFit.loose).

Mistake 3: zero flex factor. Flexible with flex=0 behaves like a non-flexible widget, which can be unintuitive. The developer expects flexible behavior, but the element occupies the minimum size. Solution: flex should be ≥1 for active space distribution.

Mistake 4: Flexible inside a ScrollView without size constraints. If Flexible is in a Column inside SingleChildScrollView, the scroll container provides infinite space, and flex distribution does not work. Solution: constrain the scroll container size using SizedBox or ConstrainedBox.

In summary: Flexible requires the same attention to the parent context as Expanded. The only difference is fit — choose it deliberately based on the task.

Frequently Asked Questions

How is Flexible different from Expanded?

Expanded is Flexible with a fixed fit=tight. The difference is that Expanded has a rigid attachment to filling all available space, while Flexible can use loose fit to preserve the child’s natural size.

Which fit should I choose for buttons in a Row?

For buttons with different text lengths, use Flexible(fit: FlexFit.loose). Each button will take the width of its content, and there will be no disproportion between them. Expanded will make all buttons the same width.

How to make Flexible behave like Expanded?

Set fit: FlexFit.tight — Flexible will force the child to fill all allocated space. In this mode, Flexible is completely identical to Expanded in behavior.

Can Flexible reduce the child’s size?

Yes, if the child is larger than the allocated space. Flexible passes constraints with a maximum size equal to the Flex container’s share. If the child exceeds this size, it shrinks within the constraints.

Does Flexible work directly with Flex container?

Yes, Flexible works with any Flex container, including Row, Column, and the base Flex widget with arbitrary direction. Flex allows setting non-standard directions via mainAxisAlignment and crossAxisAlignment.

Summary

  • Flexible is a widget for flexible space distribution without forced stretching of the child
  • FlexFit.loose preserves the natural size of content, FlexFit.tight forcibly fills the area
  • Expanded is a special case of Flexible with fit=tight, use Flexible when you need a choice of fit
  • Flex factor works the same for Flexible and Expanded — share of free space
  • Loose fit is ideal for buttons, text blocks, and elements with dynamic content
  • Recommendation: use Flexible with loose for components whose size is determined by content

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