You are currently viewing Flutter: SizedBox Widget

Flutter: SizedBox Widget

When building user interfaces in Flutter, spacing is super important. Just like a room feels better when furniture isn’t all crammed together, your app looks and works better when widgets have some breathing room. That’s where the SizedBox widget shines—it’s one of the simplest and most helpful tools for creating clean, well-spaced layouts.

In this article, we’ll explore how SizedBox works and how you can use it to make your UI look more organized and user-friendly.

What Is the SizedBox Widget?

A SizedBox is like an invisible box you can add to your layout. You can give it a specific height, width, or both. Think of it like placing a shoebox between two toys on a shelf to keep them from bumping into each other — it adds space without showing anything.

You can also wrap another widget inside a SizedBox to control how big that widget should be. It’s a simple way to manage size and spacing without extra decoration or complexity.

Basic Usage of SizedBox

There are two simple ways to use a SizedBox in your layout:

a) As a Spacer

You can use SizedBox by itself to create empty space between widgets. It’s like putting an invisible block in your layout.

Example: Spacing Between Form Fields in a Login Screen

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SizedBox Demo',
      home: const LoginPage(),
    );
  }
}

class LoginPage extends StatelessWidget {
  const LoginPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Login')),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            const TextField(decoration: InputDecoration(labelText: 'Email')),
            const SizedBox(height: 16), // Space between fields
            const TextField(
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
            ),
            const SizedBox(height: 24), // Space before button
            SizedBox(
              height: 48,
              child: ElevatedButton(
                onPressed: () {},
                child: const Text('Login'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

In this example, SizedBox adds vertical space between the email and password fields, as well as between the password field and the login button. By setting height to 16 and 24, you can easily control the gaps in your layout, making it look cleaner and more organized.

Flutter SizedBox Example 1

If you want to push things apart sideways, simply use the width instead. For example:

SizedBox(width: 10)

This will add 10 pixels of horizontal space, giving your widgets some breathing room and helping to arrange them more comfortably in the layout.

b) To Set Size for a Widget

You can also use SizedBox to control the size of a widget. Just wrap the widget inside a SizedBox and set the desired width and height.

Example: Fixed-Size Button

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SizedBox Button Example',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('SizedBox Button Example')),
      body: Center(
        child: SizedBox(
          width: 200, // Set width to 200 pixels
          height: 100, // Set height to 100 pixels
          child: ElevatedButton(
            style: ButtonStyle(
              // Define the button style
              foregroundColor: WidgetStateProperty.all(
                Colors.white,
              ), // Text color
              backgroundColor: WidgetStateProperty.all(
                Colors.pinkAccent,
              ), // Button color
              shape: WidgetStateProperty.all(
                RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(8), // Rounded corners
                ),
              ),
            ),
            onPressed: () {
              // Add functionality when the button is clicked
              ScaffoldMessenger.of(
                context,
              ).showSnackBar(const SnackBar(content: Text('Button Pressed')));
            },
            child: const Text('Login'),
          ),
        ),
      ),
    );
  }
}

In this example, the button is made exactly 200 pixels wide and 100 pixels tall—no more, no less. This ensures that the button remains a consistent size across your app, making your layout more predictable and organized. It’s especially useful when you need uniformity in button sizes or any other widget, like in the SizedBox widget, which wraps the ElevatedButton and fixes its dimensions.

Flutter SizedBox Example 2

SizedBox vs Padding vs Spacer

It can be a bit tricky to differentiate between SizedBox, Padding, and Spacer. Here’s a simple way to think about each:

  • SizedBox: Adds a fixed amount of space or sets a widget’s exact size. It’s like placing a block of wood on a shelf to create a specific gap.
  • Padding: Adds space inside a widget, around its content. Think of it like putting soft padding inside a box to prevent items from touching the edges.
  • Spacer: Fills available space flexibly. Imagine a spring that stretches to push elements apart as much as needed.

Use SizedBox when you need precise control over the amount of space or when you want to define a widget’s exact size.

Using SizedBox with No Child

When you don’t provide a child to the SizedBox, it simply acts as empty space in your layout:

Column(
  children: [
    Text('Above'),
    SizedBox(height: 30), // Adds 30 pixels of space
    Text('Below'),
  ],
)

In this example, SizedBox adds 30 pixels of vertical space between the two text widgets. It’s a straightforward and effective way to create spacing. You can use the width property in a similar way for horizontal spacing.

Using SizedBox with a Child

When you wrap a widget inside a SizedBox, you can control how big that widget appears:

SizedBox(
  width: 150,
  height: 150,
  child: Image.asset('assets/images/image.png'),
)

In this example, even if the image is larger than 150×150, it will be displayed inside a box with those exact dimensions. This is particularly useful when you want to ensure consistent sizes for widgets throughout your app.

Special Constructors

Flutter provides a few special ways to use SizedBox that make it even more versatile. Let’s explore these constructors:

SizedBox.expand()

The SizedBox.expand() constructor makes the widget fill all available space in its parent. It’s like a liquid that spreads out and fills every corner of the container.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('SizedBox.expand() Example')),
        body: Center(
          child: SizedBox.expand(
            child: Container(color: Colors.blue), // Container fills all available space
          ),
        ),
      ),
    );
  }
}

In this example, the SizedBox.expand() makes the Container fill the entire available space inside the parent widget, just like water filling a container.

Flutter SizedBox Example 3

SizedBox.square()

The SizedBox.square() constructor creates a square-shaped box where both the height and width are equal. You can specify the size with the dimension property.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('SizedBox.square() Example')),
        body: Center(
          child: SizedBox.square(
            dimension: 100, // Box is 100x100
            child: Container(
              decoration: BoxDecoration(
                border: Border.all(
                  color: Colors.blue,
                  width: 2,
                ), // Add a blue border
              ),
              child: const Icon(
                Icons.star,
                size: 50,
              ), // Icon inside the square box
            ),
          ),
        ),
      ),
    );
  }
}

Here, SizedBox.square() creates a 100×100 square box, and the Icon is centered within that square. This is useful for creating uniform shapes like avatars or icons.

Flutter SizedBox Example 4

SizedBox.fromSize()

The SizedBox.fromSize() constructor allows you to create a SizedBox from an existing Size object, giving you more flexibility when working with dynamic sizes.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('SizedBox.fromSize() Example')),
        body: Center(
          child: SizedBox.fromSize(
            size: Size(120, 80), // Custom size
            child: Container(color: Colors.green), // Container with custom size
          ),
        ),
      ),
    );
  }
}

In this example, SizedBox.fromSize() creates a box with a custom size (120x80), and the Container is displayed inside it. This constructor is great when you already have a Size object and want to reuse it in a layout.

Flutter SizedBox Example 5

SizedBox.shrink()

The SizedBox.shrink() constructor creates a box that takes up no space at all. It’s like an invisible widget that doesn’t affect the layout—but it still keeps its place in the widget tree.

This is useful when you want to include a widget in your code but not show it on the screen. It lets you hide something without breaking the layout.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('SizedBox.shrink() Example')),
        body: Center(
          child: SizedBox.shrink(
            child: Container(
              color: Colors.red,
              width: 100,
              height: 100,
            ), // This container is inside, but SizedBox.shrink hides it
          ),
        ),
      ),
    );
  }
}

What’s Going On?

  • SizedBox.shrink() makes itself as small as possible—basically invisible.
  • Even though there’s a Container inside (which normally takes space), it won’t be shown because the parent SizedBox.shrink() gives it no room to grow.
  • This is handy if you want to hide a widget completely but still keep it in your widget tree—for example, when toggling visibility based on a condition.
Flutter SizedBox Example 6

Tip

If you want the child to still take up space sometimes, you can wrap the SizedBox.shrink() in an if statement or use a ternary like this:

isVisible ? myWidget : SizedBox.shrink()

This lets you show or hide a widget without messing up your layout.

These special constructors give you flexibility in how you use SizedBox, whether you’re filling all available space, ensuring a square shape, or using a predefined size.

Best Practices

To make the most of SizedBox, here are some helpful tips:

  • Use SizedBox for Spacing: Instead of using an empty Container() to add space, use SizedBox(height: 10) or SizedBox(width: 10). It’s simpler and clearer when you just need to create space between widgets.
  • Great for Row and Column: SizedBox works perfectly in Row and Column widgets to create neat, consistent gaps between elements. It’s an easy way to maintain a clean and organized layout.
  • Don’t Overuse It: While SizedBox is handy, too many of them can clutter your layout. Instead, consider using Spacer() for flexible gaps or Padding for internal spacing. This keeps your layout more flexible and less rigid.

By following these simple guidelines, you can use SizedBox effectively to keep your UI clean and easy to manage.

Conclusion

The SizedBox widget may seem simple, but it’s a powerful tool for managing space and sizes in your Flutter layouts. Whether you’re adding space between widgets or setting precise sizes, SizedBox helps keep your UI neat and organized.

By mastering SizedBox, you can easily improve the structure of your app, making it more visually appealing and user-friendly. Start experimenting with SizedBox in your projects, and you’ll quickly see how it helps give your app some breathing room, leading to a cleaner and more polished design.