React Native Flexbox Layout

Flexbox is the layout system React Native uses to position everything on screen. Unlike web CSS where block layout is the default, React Native uses Flexbox for all layout. Once you understand Flexbox, you can build any screen layout with confidence.

The Main Idea — A Box of Items

Imagine a box of books on a shelf. The shelf is the parent container. The books are the children. Flexbox controls how the books sit on the shelf — side by side, stacked, spread out, or pushed to the corners.

┌────────────────────────────────────┐
│  Parent View (the shelf)           │
│  ┌────────┐ ┌────────┐ ┌────────┐  │
│  │ Child  │ │ Child  │ │ Child  │  │
│  │   1    │ │   2    │ │   3    │  │
│  └────────┘ └────────┘ └────────┘  │
└────────────────────────────────────┘

flexDirection — Which Way Items Stack

flexDirection sets the main axis — the direction items flow in. The default in React Native is column (top to bottom). This is different from web CSS, where the default is row.

flexDirection: 'column'   (default)     flexDirection: 'row'
─────────────────────────────────────────────────────────────
┌──────────┐                           ┌────┐ ┌────┐ ┌────┐
│  Item 1  │                           │ 1  │ │ 2  │ │ 3  │
│──────────│                           └────┘ └────┘ └────┘
│  Item 2  │
│──────────│
│  Item 3  │
└──────────┘
<View style={{ flexDirection: 'row' }}>
  <View style={{ width: 60, height: 60, backgroundColor: '#007AFF' }} />
  <View style={{ width: 60, height: 60, backgroundColor: '#34C759' }} />
  <View style={{ width: 60, height: 60, backgroundColor: '#FF3B30' }} />
</View>

justifyContent — Position Along the Main Axis

justifyContent controls how items are spread along the main axis (vertical for column, horizontal for row).

justifyContent: 'flex-start'    Items at the start
┌──────────────────┐
│ [A][B][C]        │
└──────────────────┘

justifyContent: 'flex-end'      Items at the end
┌──────────────────┐
│         [A][B][C]│
└──────────────────┘

justifyContent: 'center'        Items in the middle
┌──────────────────┐
│    [A][B][C]     │
└──────────────────┘

justifyContent: 'space-between' Items spread with gaps
┌──────────────────┐
│ [A]    [B]    [C]│
└──────────────────┘

justifyContent: 'space-around'  Items with equal padding
┌──────────────────┐
│  [A]  [B]  [C]   │
└──────────────────┘

alignItems — Position Along the Cross Axis

alignItems controls position on the axis that is perpendicular to flexDirection. If items flow in a row, alignItems controls their vertical alignment.

flexDirection: 'row' with different alignItems:

alignItems: 'flex-start'     alignItems: 'center'     alignItems: 'flex-end'
┌────────────────────┐       ┌────────────────────┐   ┌────────────────────┐
│ [A][B][C]          │       │                    │   │                    │
│                    │       │  [A][B][C]         │   │          [A][B][C] │
│                    │       │                    │   │                    │
└────────────────────┘       └────────────────────┘   └────────────────────┘
(items at the top)           (items in the middle)     (items at the bottom)

flex — Grow to Fill Space

Giving a child flex: 1 tells it to fill all available space in its parent. Multiple children with flex values share the space proportionally.

<View style={{ flex: 1, flexDirection: 'row' }}>
  <View style={{ flex: 1, backgroundColor: '#007AFF' }} />  {/* 1/3 width */}
  <View style={{ flex: 2, backgroundColor: '#34C759' }} />  {/* 2/3 width */}
</View>

Result:
┌──────────────────────────────┐
│   Blue   │       Green       │
│  (1/3)   │      (2/3)        │
└──────────────────────────────┘

Common Layout Patterns

Centering Everything

<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
  <Text>I am perfectly centered</Text>
</View>

┌─────────────────────────┐
│                         │
│                         │
│  I am perfectly         │
│  centered               │
│                         │
│                         │
└─────────────────────────┘

Header + Content + Footer

<View style={{ flex: 1 }}>
  <View style={{ height: 60, backgroundColor: '#007AFF' }}>
    <Text>Header</Text>
  </View>

  <View style={{ flex: 1 }}>   {/* Takes all remaining space */}
    <Text>Main Content Area</Text>
  </View>

  <View style={{ height: 60, backgroundColor: '#E5E5EA' }}>
    <Text>Footer / Tab Bar</Text>
  </View>
</View>

┌─────────────────────┐
│       Header        │  ← fixed 60px
├─────────────────────┤
│                     │
│    Main Content     │  ← flex: 1 (fills gap)
│                     │
├─────────────────────┤
│       Footer        │  ← fixed 60px
└─────────────────────┘

Icon + Text Row (Common List Item)

<View style={{ flexDirection: 'row', alignItems: 'center', padding: 16 }}>
  <View style={{ width: 40, height: 40, borderRadius: 20, backgroundColor: '#007AFF' }} />
  <View style={{ marginLeft: 12, flex: 1 }}>
    <Text style={{ fontWeight: 'bold' }}>John Smith</Text>
    <Text style={{ color: '#666' }}>Last message here...</Text>
  </View>
  <Text style={{ color: '#999' }}>2m ago</Text>
</View>

Result:
┌──────────────────────────────────────────┐
│ [●]  John Smith              2m ago      │
│      Last message here...                │
└──────────────────────────────────────────┘

flexWrap — Allow Items to Wrap

By default, items stay on one line even if they overflow. Set flexWrap: 'wrap' to let items move to the next line when there is no more horizontal space.

<View style={{ flexDirection: 'row', flexWrap: 'wrap' }}>
  {/* Tags that wrap to the next line */}
  <Text style={{ margin: 4, padding: 8, backgroundColor: '#E3F2FD' }}>React</Text>
  <Text style={{ margin: 4, padding: 8, backgroundColor: '#E3F2FD' }}>Native</Text>
  <Text style={{ margin: 4, padding: 8, backgroundColor: '#E3F2FD' }}>Mobile</Text>
  <Text style={{ margin: 4, padding: 8, backgroundColor: '#E3F2FD' }}>JavaScript</Text>
</View>

┌──────────────────────────┐
│ [React] [Native] [Mobile]│
│ [JavaScript]             │  ← wrapped to next line
└──────────────────────────┘

Summary

Every React Native layout uses Flexbox. The default direction is column (top to bottom). Use justifyContent to position items along the main axis and alignItems for the cross axis. Use flex: 1 on a child to make it fill remaining space. These four properties handle 90% of all layout tasks you will encounter.

Leave a Comment