Row and Column in Flutter

Master the fundamental widgets for organizing your user interface

Download Complete Examples

What are Row and Column?

Row and Column are the most important widgets in Flutter for organizing other widgets on the screen. They are flex layout widgets that arrange their children in a specific direction.

Row

Organizes widgets horizontally from left to right

1
2
3

Column

Organizes widgets vertically from top to bottom

1
2
3

Basic Syntax

Row Basics

Row(
  children: [
    Text('Element 1'),
    Text('Element 2'),
    Text('Element 3'),
  ],
)

Column Basics

Column(
  children: [
    Text('Element 1'),
    Text('Element 2'),
    Text('Element 3'),
  ],
)

Main Properties

mainAxisAlignment

Alignment on the main axis

start end center spaceBetween spaceAround spaceEvenly

crossAxisAlignment

Alignment on the cross axis

start end center stretch

mainAxisSize

Size on the main axis

max min

mainAxisAlignment

Controls how widgets are distributed along the main axis (horizontal for Row, vertical for Column).

Examples in Row:

MainAxisAlignment.start
Home
A
B
C
Fin
MainAxisAlignment.center
Home
A
B
C
Fin
MainAxisAlignment.spaceBetween
Home
A
B
C
Fin

Código de Ejemplo:

Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    Container(width: 50, height: 50, color: Colors.red),
    Container(width: 50, height: 50, color: Colors.green),
    Container(width: 50, height: 50, color: Colors.blue),
  ],
)

crossAxisAlignment

Controls how widgets are aligned on the cross axis (vertical for Row, horizontal for Column).

Examples in Column:

CrossAxisAlignment.start
Home
A
B
C
Fin
CrossAxisAlignment.center
Home
A
B
C
Fin
CrossAxisAlignment.stretch
Home
A
B
C
Fin

Practical Examples

1. Top Navigation Bar

Row(
  children: [
    IconButton(icon: Icon(Icons.menu), onPressed: () {}),
    Expanded(
      child: Text('Mi Aplicación', textAlign: TextAlign.center),
    ),
    IconButton(icon: Icon(Icons.search), onPressed: () {}),
    IconButton(icon: Icon(Icons.settings), onPressed: () {}),
  ],
)

2. Profile Card

👤
Juan Pérez
juan@email.com
➡️
Row(
  children: [
    CircleAvatar(backgroundImage: NetworkImage(url)),
    SizedBox(width: 16),
    Expanded(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('Juan Pérez', style: TextStyle(fontWeight: FontWeight.bold)),
          Text('juan@email.com'),
        ],
      ),
    ),
    Icon(Icons.chevron_right),
  ],
)

3. Login Form

Column(
  children: [
    TextField(decoration: InputDecoration(labelText: 'Email')),
    SizedBox(height: 16),
    TextField(decoration: InputDecoration(labelText: 'Password'), obscureText: true),
    SizedBox(height: 24),
    Row(
      children: [
        Expanded(child: TextButton(child: Text('Cancel'), onPressed: () {})),
        SizedBox(width: 16),
        Expanded(child: ElevatedButton(child: Text('Log In'), onPressed: () {})),
      ],
    ),
  ],
)

Tester for Row and Column

3 widgets
1
2
3
// El código se generará aquí

Row vs Column - When to use each one?

Aspect Row Column
Address Horizontal Vertical
Main Axis Horizontal Vertical
Cross Axis Vertical Horizontal
Use Cases Navigation bars, data rows, inline buttons Forms, lists, vertically scrolling pages
Example Icon + Text + Button Title + Image + Description + Button

Special Child Widgets

Expanded

Takes up the available space on the main axis

Fixed
Expandido
Fixed
Row( children: [ Container(width: 50, color: Colors.red), Expanded( child: Container(color: Colors.blue), ), Container(width: 50, color: Colors.green), ], )

Flexible

Similar to Expanded but with custom flex

Flex 2
Flex 1
Flex 1
Row( children: [ Flexible(flex: 2, child: Container(color: Colors.red)), Flexible(flex: 1, child: Container(color: Colors.green)), Flexible(flex: 1, child: Container(color: Colors.blue)), ], )

Spacer

Creates flexible space between widgets

Home
Fin
Row( children: [ Text('Home'), Spacer(), Text('Fin'), ], )

Common Errors and Solutions

❌ "Vertical viewport was given unbounded height"

Problem: A Column inside a ListView without a defined height

Solution: Use SingleChildScrollView or wrap in Expanded

// MALListView(children: [Column(children: [...]))])

// BIENSingleChildScrollView(child: Column(children: [...]))

❌ "RenderFlex overflowed by ... pixels"

Problem: The widgets don't fit on the screen

Solution: Use SingleChildScrollView or reduce the content

// MALColumn(children: [/* mucho contenido */])

// BIENSingleChildScrollView(child: Column(children: [...]))

❌ Widgets don't align correctly

Problem: crossAxisAlignment misconfigured

Solution: Use CrossAxisAlignment.stretch or define widths

Column(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    Container(height: 50, color: Colors.red),
    Container(height: 50, color: Colors.blue),
  ],
)

Tips and Best Practices

🎯 Use SizedBox for spacing

Instead of Padding to separate widgets, use SizedBox, which is more efficient:

Column( children: [ Text('Title'), SizedBox(height: 16), // Mejor que Padding Text('Subtitle'), ], )

📱 Considera responsive design

Use LayoutBuilder or MediaQuery to adapt Row/Column to different screen sizes:

LayoutBuilder( builder: (context, constraints) { if (constraints.maxWidth > 600) { return Row(children: [...]); // Tablet } else { return Column(children: [...]); // Móvil } }, )

⚡ Optimize with const

Use const constructors for widgets that don't change:

Column( children: const [ Text('Title'), SizedBox(height: 16), Text('Subtitle'), ], )

Exercises to Practice

Exercise 1: Toolbar

Create a toolbar with centered icons and space between them.

Hint: Use Row with MainAxisAlignment.spaceEvenly

Exercise 2: Registration Form

Create a form with fields stacked vertically and buttons aligned to the right.

Hint: Combine Column and Row with CrossAxisAlignment.end

Exercise 3: Product Card

Create a card with an image on the left and text on the right that takes up the remaining space.

Hint: Use Row with Expanded around the text