FractionallySizedBox widget in Flutter: Use percentage sizes

- 👤 Andrés Cruz

🇪🇸 En español

FractionallySizedBox widget in Flutter: Use percentage sizes

We are going to learn about a very special widget that will get us out of trouble in many cases. Surely you've run into the situation where you want to place an element that occupies 40%, 60%, 10%, etc., and you don't know how to do it. You could use MediaQueries, but these should be used for something much more specific, and besides, we'll show you an easier way to do it.

In this guide, I tell you how it works, when to use it, examples, common errors, comparisons, and several tricks I learned "the hard way."

We agreed that we know how to implement tap or click events in ANY widget with GestureDetector.

What is FractionallySizedBox and why it's key in responsive layouts

FractionallySizedBox is a widget that adjusts the size of its child to a fraction of the parent's available space. That fraction is defined with two properties:

widthFactor: porcentaje de ancho (0 a 1).
heightFactor: porcentaje de alto (0 a 1).

That is:

childWidth = parentWidth * widthFactor
childHeight = parentHeight * heightFactor

This makes calculating spaces in percentages very simple.

How FractionallySizedBox works

WidthFactor and HeightFactor in plain terms

  • 0.0 means invisible.
  • 1.0 means 100% of the available space.
  • Intermediate values (0.3, 0.6, 0.8...) represent percentages.
  • Values > 1 cause overflow (not recommended).

Typical example of 50% width:

FractionallySizedBox(
 widthFactor: 0.5,
 child: ElevatedButton(
   onPressed: () {},
   child: Text("Hola"),
 ),
)

Examples

The FractionallySizedBox Widget allows us to create a container that occupies only a fraction (according to the value set between 0 and 1) of the total container space. This description might sound a bit confusing, so let's see it in practice. We are going to specify a single screen, meaning we will have all the available space using a simple Scaffold:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FractionallySizedBox',
      home: Scaffold(
          appBar: AppBar(
            title: Text("FractionallySizedBox"),
          ),
          body: Center(),
      )
    );
  }
}
Basic Flutter project structure

We simply have the basic structure: an AppBar with some text and a completely empty Center in the body.

Defining half the width in percentages

Now that we have all the available space of that Scaffold, we are going to place our FractionallySizedBox as the container element so that it occupies a fraction of the container according to the value we specify. For example, we want it to occupy half the width:

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FractionallySizedBox',
      home: Scaffold(
          appBar: AppBar(
            title: Text("FractionallySizedBox"),
          ),
          body: FractionallySizedBox(
              //alignment: Alignment.center,
              widthFactor: 0.5,
              //heightFactor: 0.5,
              child: Container(
                child: RaisedButton(
                  child: Text("Hola"),
                  onPressed: NULL,
                ),
              ))),
    );
  }
FractionallySizedBox with half the width

As you can see in the previous example, we set a widthFactor of 0.5, and this translates in practice to an element that occupies half the width of the entire screen, since remember that our FractionallySizedBox has all the space of its parent container available as it is the root element of the Scaffold.

Defining half the height in percentages

Let's now define the factor for the height or the heightFactor of our fractional container:

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FractionallySizedBox',
      home: Scaffold(
          appBar: AppBar(
            title: Text("FractionallySizedBox"),
          ),
          body: FractionallySizedBox(
              //alignment: Alignment.center,
              //widthFactor: 0.5,
              heightFactor: 0.5,
              child: Container(
                child: RaisedButton(
                  child: Text("Hola"),
                  onPressed: NULL,
                ),
              ))),
    );
  }
FractionallySizedBox with half the height

It is exactly the same code, only we varied the factor from width to height, and for this reason, it now occupies half the height. As you can assume, the factor goes from zero (totally invisible) to 1 (occupies all the space). Everything in between (a double value between 0 and 1, excluding these) means we occupy a fraction of the container in proportion equal to the value you specify.

Aligning a widget in the middle of the screen

We can also align the element contained within our FractionallySizedBox, which in this case would be our RaisedButton. For this, we use the Alignment property. Although in these examples our FractionallySizedBox makes our button occupy the full width, if we use another type of container, for example, a Center:

@override
    Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FractionallySizedBox',
      home: Scaffold(
          appBar: AppBar(
            title: Text("FractionallySizedBox"),
          ),
          body: Center(
            child: FractionallySizedBox(
                alignment: Alignment.center,
                //widthFactor: 0.5,
                heightFactor: 0.5,
                child: Container(
                  child: RaisedButton(
                    child: Text("Hola"),
                    onPressed: NULL,
                  ),
                )),
          )),
    );
  }
FractionallySizedBox with Center

Using FractionallySizedBox with Columns and/or Rows

If you want to use a Column inside a Row or FractionallySizedBox, you must specify a Flexible widget.

Column(
            children: <Widget>[
              Flexible(
                child: FractionallySizedBox(
                    //alignment: Alignment.center,
                    //widthFactor: 0.5,
                    heightFactor: 0.5,
                    child: Center(
                      child: RaisedButton(
                        child: Text("Hola"),
                        onPressed: NULL,
                      ),
                    )),
              ),
            ],
          ))
FractionallySizedBox with columns and rows

Adaptive Dialogs

To give exactly the size you want for your dialog:

showDialog(
 context: context,
 builder: (_) => Dialog(
   child: FractionallySizedBox(
     widthFactor: 0.75,
     child: Padding(
       padding: EdgeInsets.all(16),
       child: Column(
         mainAxisSize: MainAxisSize.min,
         children: [
           Text("Diálogo responsivo"),
           SizedBox(height: 10),
           ElevatedButton(
             onPressed: () => Navigator.pop(context),
             child: Text("Cerrar"),
           )
         ],
       ),
     ),
   ),
 ),
);

Responsive Grid (galleries, cards, images)

FractionallySizedBox(
 widthFactor: 0.95,
 heightFactor: 0.95,
 child: Container(
   decoration: BoxDecoration(
     borderRadius: BorderRadius.circular(8),
   ),
 ),
)

Using it in Column/Row without Flexible

Without Flexible, the widget doesn't know how much to measure:

Column(
 children: [
   Flexible(
     child: FractionallySizedBox(
       heightFactor: 0.5,
       child: Container(color: Colors.red),
     ),
   ),
 ],
)

50% width

FractionallySizedBox( widthFactor: 0.5, child: Container(color: Colors.red), )

40% height

FractionallySizedBox( heightFactor: 0.4, child: Container(color: Colors.green), )

Common mistakes and how to avoid them

  • ❌ Using widthFactor > 1 → immediate overflow
  • ❌ Nesting multiple FractionallySizedBox unnecessarily
  • ❌ Using it inside Column/Row without Flexible
  • ❌ Expecting results without the parent having a clear size
  • ❌ Forgetting that negative values cause an error

Conclusion

FractionallySizedBox is one of those widgets that seems simple... but unlocks a completely new level of responsive design in Flutter.
It allowed me to move beyond MediaQuery for basic tasks, center elements without fighting with pixels, and create much cleaner layouts.

When you understand how it behaves in relation to its parent, it becomes a tool you use without thinking.

FAQs

  • What happens if I use widthFactor greater than 1?
    • It causes overflow. Not recommended except in very controlled cases.
  • Why doesn't my FractionallySizedBox occupy the correct space?
    • The parent probably doesn't have restrictions. Use Flexible, Expanded, SizedBox, or Center.
  • Can I combine widthFactor and heightFactor?
    • Yes, it is totally valid.
  • Is FractionallySizedBox or MediaQuery better?
    • For simple percentages → FractionallySizedBox.
    • For complex calculations → MediaQuery.

Next widget to study: the Swipe Detector to detect swipes in Flutter.

I agree to receive announcements of interest about this Blog.

The FractionallySizedBox widget allows you to align elements so that they occupy a percentage of the parent element and is an option to MediaQueries.

| 👤 Andrés Cruz

🇪🇸 En español