Ivy Walobwa Ivy is a Flutter developer and technical writer who is interested in creating awesome developer experiences. She is currently a Program Assistant for the Google Africa Developer Scholarship (GADS), where she helps facilitate the learning of students across Africa.

Flutter layouts guide: Margins and padding

4 min read 1350

Flutter Layouts Guide Margins And Padding

The UI of a Flutter application is made up of various widgets put together. Some of these widgets are visible, while others are not.

Visible widgets display elements to the user, such as text or images. Invisible widgets, or layout widgets, define how the visible ones are laid out on the screen.

Layout widgets are essential to your app’s success. The composition of your widgets determine how users will interact with your app. Flutter offers several widgets, like Container and Padding, for the purpose of laying out your UI.

In this tutorial, we’ll introduce Flutter’s box model, a concept used when discussing layouts. We’ll also learn how to implement margin and padding to lay out widgets in our Flutter app.

The box model

The box model is a box containing the content, padding, border, and margin of a displayed widget. The goal is to ensure that the developer has a well-modeled UI.

The Box Model

Within the box model, let’s break down the components.

The first is content. Content is the visible element that can be sized using width and height properties.

Next, we have padding. This is the empty space around the content. Its value is included in the width and height of the visible element.

Then, we have the border. A border wraps around the padding and content. Its value is included in the padding of the visible element as well.



Lastly, we have the margin. This is the empty space around the visible element. It’s completely invisible and clears the area outside the border.

The Container widget

Flutter offers a Container widget that can be used to implement the box model in our apps. Container is convenient because it can be used to manage multiple widgets’ widths, heights, margins, padding, colors, and more. It does this by combining common painting, positioning, and sizing widgets.

The margin and padding properties of Container are used to set the margin and padding (makes sense, right?) for the visible elements in our UI.

The app below renders two Text widgets inside the Container. The colors of each Container have been set to clearly demonstrate the effects of setting the margin and padding in the example below:

Row(
  mainAxisAlignment: MainAxisAlignment.start,
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    Container(
      child: Text(
        "text 1",
        style: TextStyle(fontSize: 32),
      ),
      decoration: BoxDecoration(color: Colors.yellow),
    ),
    Container(
      child: Text(
        "text 2",
        style: TextStyle(fontSize: 32),
      ),
      decoration: BoxDecoration(color: Colors.green),
    ),
  ],
),

The Container Widget Text

The code snippet above paints two Containers side by side without any whitespace. We’ll need to set the margin and padding for the visible Text widget. But before we do that, it’s important that we have an understanding of the EdgeInsets class.

The EdgeInsets class

The margin and padding properties of a Container widget expect a value of the type EdgeInsetsGeometry, an abstract class. This means that that EdgeInsetsGeometry can’t be used directly so we have to make use of its subclasses, EdgeInsets and EdgeInsetsDirectional, to set the margin and padding.


More great articles from LogRocket:


EdgeInsets sets margin and padding based on the left, top, right, and bottom direction parameters. EdgeInsetsDirectional, on the other hand, sets margin and padding based on the start, top, end, and bottom direction parameters.

The main difference between the two is that EdgeInsetsDirectional is a locale direction-aware widget, unlike EdgeInsets.

We can set the insets of theEdgeInsets class using the following properties:

  • EdgeInsets.zero: Sets a zero offset in all directions
  • EdgeInsets.all: Sets one common offset in all directions
  • EdgeInsets.only: Sets an offset only in the specified directions. The left, top, right, and bottom directions can be specified in any order
  • EdgeInsets.fromLTRB: Sets an offset in all directions based on the value passed for each. The directions have to be specified in the left, top, right, and bottom order.
  • EdgeInsets.symmetric: Sets a vertical or horizontal offset

We can set the insets of the EdgeInsetsDirectional class using the following properties:

  • EdgeInsets.zero: Sets a zero offset in all directions
  • EdgeInsets.all: Sets one common offset in all directions
  • EdgeInsets.only: Sets an offset only in the specified directions. The start, top, end, and bottom directions can be specified in any order
  • EdgeInsets.fromSTEB: Sets an offset in all directions based on the value passed for each. The directions have to be specified in the start, top, end, and bottom order

In this tutorial, we’ll use the EdgeInsets class.

Setting the margin

The margin property of Container is used to set the margin. It adds an empty space around the Container.

First, we’ll add a margin around the first Container as shown below:

Container(
  margin: EdgeInsets.all(24),
  child: Text(
    "text 1",
    style: TextStyle(fontSize: 32),
  ),
  decoration: BoxDecoration(color: Colors.yellow),
)

Setting The Margin One

Next, we’ll add a top margin to the second Container only:

Container(
  margin: EdgeInsets.only(top: 24),
  child: Text(
    "text 2",
    style: TextStyle(fontSize: 32),
  ),
  decoration: BoxDecoration(color: Colors.green),
)

Setting The Margin Two

Our widgets are now separated with an empty space.

Setting the padding

The padding property of Container is used to add empty space inside the decorated Container. We’ll add horizontal and vertical padding to our widgets, as shown in the code below:

padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12)

This code snippet adds horizontal and vertical padding to our widgets. It sets an offset of 20 to the left and right and an offset of 12 to the top and bottom.

Setting The Padding

Our content is now padded and looks better!

Dynamically setting the margin and padding

Setting a hardcoded value for our margin and padding will likely only look good on our testing device. On different screen sizes, the intended layout might not be what the user actually sees. Therefore, it is important to set the margin and padding dynamically based on screen size.

We’ll use the MediaQuery class to get the screen size of our app. Then, we’ll be able to dynamically set the margin and padding based on the size of the widgets.

MediaQuery And Setting Padding

First, we’ll store the device’s width and height values in variables like this:

Widget build(BuildContext context) {
  final height = MediaQuery.of(context).size.height;
  final width = MediaQuery.of(context).size.width;
  return ...

Next, we’ll set the margin and padding properties as a fraction of the device’s width and height:

margin: EdgeInsets.symmetric(horizontal: width *0.1, vertical: height *0.05),
padding: EdgeInsets.symmetric(horizontal: width *0.05,vertical: height*0.05),

This lays out our widgets with margin and padding that adapt to different sized screens.

Margin And Padding For Different Sized Screens

Decorating the boxes

We can add some decorations to our container using the decoration property. This expects the abstract class for all decorations, called the Decoration class, and applies the styles to our widget.

The code snippet below uses the BoxDecoration class to add a color, border, border radius, and box shadow to the Container.

decoration: BoxDecoration(
  color: Colors.yellow,
  borderRadius: BorderRadius.circular(10),
  border: Border.all(),
  boxShadow: [
    BoxShadow(
      color: Colors.grey.withOpacity(0.5),
      spreadRadius: 5,
      blurRadius: 7,
      offset: const Offset(0, 3),
    ),
  ],
),

Decorating The Boxes

The Padding widget

We may need to add padding to a widget that does not implement the Padding class in its properties. For instance, the Card widget below draws a card with text in it.

Center(
  child: Card(
    color: Colors.yellow,
    child: Text(
      "Card text",
      style: TextStyle(fontSize: 32),
    ),
  ),
)

Padding Widget One

To add some space around the text, we can wrap the Text widget with a Padding widget. The Padding widget requires a padding property. The property is set to add empty space around the desired widget via the EdgeInsetsGeometry class.

child: Center(
  child: Card(
    color: Colors.yellow,
    child: Padding(
      padding: EdgeInsets.all(24.0),
      child: Text(
        "Card text",
        style: TextStyle(fontSize: 32),
      ),
    ),
  ),
)

Padding Widget Two

Conclusion

In this tutorial, we discussed the box model and looked into how margins and paddings can be used to build layouts in Flutter. We also looked into the Container widget and how to set its margin, padding, and decorations. Finally, we used the Padding widget to add padding.

With that, you are now able to carefully lay out widgets in your UI to enhance your user interactions. All the code in this article is available on GitHub.

I hope you enjoyed this tutorial!

: Full visibility into your web and mobile apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page web and mobile apps.

.
Ivy Walobwa Ivy is a Flutter developer and technical writer who is interested in creating awesome developer experiences. She is currently a Program Assistant for the Google Africa Developer Scholarship (GADS), where she helps facilitate the learning of students across Africa.

One Reply to “Flutter layouts guide: Margins and padding”

  1. Just starting my journey in Flutter development. Thank you Ivy for this detailed piece.

Leave a Reply