Skip to content

Intermediate · Layouts · topic 17 of 50 · 30 min

Row and Column

Explanation

Column places children vertically and Row horizontally. The main axis is the direction they lay out (vertical for Column, horizontal for Row); the cross axis is the other one. mainAxisAlignment spaces children along the main axis, crossAxisAlignment positions them across it, and mainAxisSize decides whether the Row or Column takes all available space or only what it needs.

The two workhorses

Almost every screen is built from Rows and Columns nested inside each other. A product card is a Row (image, then text); the text part is a Column (name, price, rating). Once you understand their two axes, most layouts become easy.

output
Column (main axis: vertical)          Row (main axis: horizontal)
┌───────────────┐                      ┌──────────────────────────┐
│   [ child 1 ] │  ↓ main axis         │ [c1] [c2] [c3]  → main   │
│   [ child 2 ] │                      └──────────────────────────┘
│   [ child 3 ] │  ↔ cross axis           ↕ cross axis
└───────────────┘
mainAxisAlignment works along the arrow; crossAxisAlignment works across it.
dart
Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: const [
    Text('Masala dosa'),
    Text('Rs 90'),
  ],
)
spaceBetween pushes the name to the left edge and the price to the right edge.
MainAxisAlignmentEffect
start (default)Children packed at the start
center / endPacked in the middle / at the end
spaceBetweenFirst and last at the edges, equal space between
spaceAroundEqual space around each child (half-size at the edges)
spaceEvenlyEqual space between and at the edges

crossAxisAlignment options include start, center (default), end and stretch. stretch makes children fill the cross axis, for example full-width buttons in a Column.

A good habit when you look at any design: draw boxes around it. Ask "is this a vertical list of things or a horizontal one?" Mark each group as a Row or a Column, and work from the outside in. A login screen is a Column; inside it, the "Forgot password? Sign up" line is a Row.

Row and Column do not scroll. If their children do not fit, you get an overflow error (topic 4). For content that can be longer than the screen, use a scrolling widget such as ListView or SingleChildScrollView.

mainAxisSize

By default a Column tries to be as tall as its parent allows (mainAxisSize: MainAxisSize.max). Inside a Center, that means the Column fills the screen height and its children sit at the top. MainAxisSize.min makes the Column only as tall as its children, so Center can really centre it.

Spacing between children

dart
Column(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    const TextField(decoration: InputDecoration(labelText: 'Name')),
    const SizedBox(height: 12),          // fixed gap
    const TextField(decoration: InputDecoration(labelText: 'Mobile')),
    const SizedBox(height: 24),
    ElevatedButton(onPressed: () {}, child: const Text('Continue')),
  ],
)
SizedBox gives a fixed gap. Recent Flutter versions also have a spacing parameter on Row and Column; check your Flutter version before using it.

Nesting

dart
Row(
  children: [
    const Icon(Icons.storefront, size: 40),
    const SizedBox(width: 12),
    Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: const [
        Text('Sharma General Store'),
        Text('Open till 10 pm'),
      ],
    ),
  ],
)
A Column inside a Row: the common "icon with two lines of text" pattern.
Think of it like this: A Column is like a stack of thalis on a shelf, one above another; a Row is like steel glasses lined up on a counter. mainAxisAlignment is how you spread them along the shelf or counter; crossAxisAlignment is whether they line up at the front, middle or back.

Common mistakes

  • Wrapping a Column in Center and wondering why it is still at the top: set mainAxisSize: MainAxisSize.min.
  • Too many Rows in a narrow screen: text overflows. See topic 4 for fixes with Expanded and Flexible.
  • Using spaceBetween with only one child: nothing visible happens.
  • Forgetting that crossAxisAlignment.stretch in a Row needs a bounded height.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Row and Column · 1/6

Column ↓ Row →

Column stacks children vertically. Row places them side by side.

Prefer a video by a teacher? Find free videos on “flutter row column mainaxisalignment crossaxisalignment tutorial” on YouTube ↗

In real life: A bill summary row

A restaurant billing app shows each line of the bill as "item on the left, amount on the right", with the total in bold at the bottom. A Column of Rows with MainAxisAlignment.spaceBetween does it cleanly, and the same widget works on small and large phones.

dart
class BillLine extends StatelessWidget {
  const BillLine(this.label, this.amount, {super.key, this.bold = false});
  final String label;
  final int amount;
  final bool bold;

  @override
  Widget build(BuildContext context) {
    final style = bold ? const TextStyle(fontWeight: FontWeight.bold) : null;
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [Text(label, style: style), Text('Rs $amount', style: style)],
    );
  }
}

// Column(children: const [BillLine('Thali', 180), BillLine('Lassi', 60), BillLine('Total', 240, bold: true)])
Reusable and readable.

Practice (0/3 done)

Task 1 · Question

In a Row, which property controls horizontal spacing between children?

Task 2 · Question

A Column inside Center still appears at the top of the screen. What is the usual fix?

Task 3 · Practice

Build a "contact card": a Row with a CircleAvatar on the left and a Column on the right (name in bold, phone, city), and below it a Row of three buttons (Call, SMS, WhatsApp) spaced evenly. Try every MainAxisAlignment value on the button row and note the difference.

Quick quiz

Question 1

1.What is the main axis of a Column?

Question 2

2.Which MainAxisAlignment puts equal space between children and at both edges?

Question 3

3.What does crossAxisAlignment: CrossAxisAlignment.stretch do in a Column?

Question 4

4.Which widget is commonly used for a fixed gap between children?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What is the main axis of a Column?

Answer: Vertical

Columns lay out vertically.

Which MainAxisAlignment puts equal space between children and at both edges?

Answer: spaceEvenly

spaceEvenly also spaces the edges.

What does crossAxisAlignment: CrossAxisAlignment.stretch do in a Column?

Answer: Stretches children to fill the width

For a Column the cross axis is horizontal.

Which widget is commonly used for a fixed gap between children?

Answer: SizedBox

SizedBox(height: 12) or SizedBox(width: 12).

Is nesting Rows and Columns expensive in Compose?Related

Answer: No, nesting is cheap; write clear code

Compose measures each child once.

From Layouts: Column, Row, Box and Scaffold

In a row, which property centres items vertically?Related

Answer: align-items

In a row the cross axis is vertical, and align-items works on the cross axis.

From Flexbox

m has shape (100, 5): 100 customers, 5 features. What shape does m.mean(axis=0) have?Related

Answer: (5,)

axis=0 collapses the rows, leaving one mean per column: 5 values.

From NumPy: fast arrays of numbers

Which property lets children draw outside the Stack's bounds?Related

Answer: clipBehavior: Clip.none

The default clips.

From Stack, Positioned and Align

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 4 more topics in “Layouts” before its exam: Container, Padding, SizedBox, Expanded and Flexible, Stack, Positioned and Align, Understanding constraints and fixing overflow, Images, icons, fonts and themes.
  2. Module 5 exam: Layouts · 13 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Lists, navigation and forms. 50 topics left in the course before the final exam.

← Previous: Stateless and stateful widgets