Spencer Carli Spencer is a fullstack developer primarily building cross-platform apps with React Native and teaching others to do the same at React Native School.

A guide to Flexbox properties in React Native

9 min read 2590

A Guide To Flexbox Properties In React Native

If you have a web design and/or development background, you may be familiar with Flexbox. It’s an opt-in CSS tool that enables you to build layouts based on columns and rows.

In React Native, this is the default way to build layouts. It works wonderfully for mobile development because it allows us to build layouts that fit multiple screen sizes, thanks to responsive design.

Flexbox: Developing for React Native vs. the web

Flexbox is the default in React Native, but we don’t have to opt into it, meaning you don’t need to set display: flex in a style.

const styles = StyleSheet.create({
  card: {
    display: 'flex' // this is unnecessary
  }
});

There are also different defaults that make Flexbox more conducive to mobile development:

Property Web Default React Native Default
flexDirection row column
alignContent stretch flex-start
flexShrink 1 0

Primary Flexbox properties

There are a few Flexbox properties you’ll use regularly that are worth remembering. Here’s a run down on them and what they do.

  • flex – defines how much of that view will fill the screen. Available values are integers greater than or equal to 0
  • flexDirection – determines in which direction — vertically or horizontally — the children are laid out. Available values include column, row, column-reverse, and row-reverse
  • justifyContent – determines how an item should be rendered along the primary axis (determined by the flexDirection property). Available values are flex-start, flex-end, center, space-between, space-around, and space-evenly
  • alignItems – this determines how an item should be rendered along the secondary axis (determined by the flexDirection property). Available values are flex-start, flex-end, center, and baseline
  • alignSelf – determines how a child should align itself and overrides alignItems. Available values are flex-start, flex-end, center, and baseline

You can learn more about layouts in Flexbox in the official docs. Now, let’s dive into what each property does and how to use it.

Using the flex property in Flexbox and React Native

The flex property determines how the view fills the screen. To illustrate, let’s take a look at two examples with very similar code.

Notice that the available values include integers greater than or equal to 0.

import React from "react";
import { StyleSheet, View } from "react-native";

export default function App() {
  return (
    <>
      <View style={{ backgroundColor: "#7cb48f", flex: 1 }} />
    </>
  );
}

Here’s the result:

Flex Property Filling Entire Mobile Screen Green

We made a custom demo for .
No really. Click here to check it out.

In this case, the view will take up the entire screen. Why? Because it has a property of flex: 1, and because the space is split into one group (1/1), it will take up 100% of the screen.

Let’s look at a second example using the following code:

import React from "react";
import { StyleSheet, View } from "react-native";

export default function App() {
  return (
    <>
      <View style={{ backgroundColor: "#7cb48f", flex: 1 }} />
      <View style={{ backgroundColor: "#7CA1B4", flex: 3 }} />
    </>
  );
}

Flex Property Filling Top Quarter Of Mobile Screen In Green

Alternatively, we can see that the green area now takes up just one-quarter of the screen despite having the same flex value. That’s because the screen is now split into four blocks (1+3), so the flex property is the fraction of the screen it should take up.

Using flexDirection in Flexbox

FlexDirection determines the direction children should render. You can code with values: column, row, column-reverse, and row-reverse, but the default is column.

import React from "react";
import { StyleSheet, View } from "react-native";

export default function App() {
  return (
    <>
      <View style={styles.container}>
        <View style={styles.square} />
        <View style={styles.square} />
        <View style={styles.square} />
      </View>
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#7CA1B4",
    flex: 1,
    alignItems: "center", // ignore this - we'll come back to it
    justifyContent: "center", // ignore this - we'll come back to it
    flexDirection: "column"
  },
  square: {
    backgroundColor: "#7cb48f",
    width: 100,
    height: 100,
    margin: 4,
  },
});

Flex Direction Property Creating A Column Of Three Green Squares On The Center Of Mobile Screen
Now, let’s change the direction from a column to a row using flexDirection of row.

import React from "react";
import { StyleSheet, View } from "react-native";

export default function App() {
  return (
    <>
      <View style={styles.container}>
        <View style={styles.square} />
        <View style={styles.square} />
        <View style={styles.square} />
      </View>
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#7CA1B4",
    flex: 1,
    alignItems: "center", // ignore this - we'll come back to it
    justifyContent: "center", // ignore this - we'll come back to it
    flexDirection: "row",
  },
  square: {
    backgroundColor: "#7cb48f",
    width: 100,
    height: 100,
    margin: 4,
  },
});

Flex Direction Property Creating Row Of Three Green Squares On Mobile Screen

Note that using *-reverse just reverses the order they’re rendered in.

Using the justifyContent property in Flexbox

justifyContent determines content along the primary axis that is affected by the flexDirection. If flexDirection is column, then it’s vertical. If it’s classified as row, it’s horizontal.

As a reminder, here are the available values: flex-start, flex-end, center, space-between, space-around, and space-evenly.

Below we’ve set justifyContent to center. Because the primary axis is a column that means we’ll be centering the content vertically.

import React from "react";
import { StyleSheet, View } from "react-native";

export default function App() {
  return (
    <>
      <View style={styles.container}>
        <View style={styles.square} />
        <View style={styles.square} />
        <View style={styles.square} />
      </View>
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#7CA1B4",
    flex: 1,
    justifyContent: "center",
  },
  square: {
    backgroundColor: "#7cb48f",
    width: 100,
    height: 100,
    margin: 4,
  },
});

Justify Content Property Creating Row Of Three Green Squares On The Left Side Of Mobile Screen

Next, we’ve used the space-around property. This is going to cause the layout to split the elements along the primary (vertical) axis evenly. This means that there will be an equal amount of distance from the top and bottom of the screen as there is between each element.

import React from "react";
import { StyleSheet, View } from "react-native";

export default function App() {
  return (
    <>
      <View style={styles.container}>
        <View style={styles.square} />
        <View style={styles.square} />
        <View style={styles.square} />
      </View>
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#7CA1B4",
    flex: 1,
    justifyContent: "space-around",
  },
  square: {
    backgroundColor: "#7cb48f",
    width: 100,
    height: 100,
    margin: 4,
  },
});

Space Around Property Increased Space In Between Three Green Squares On The Left Side Of Mobile Screen

Each of these properties allows you to make a unique layout. flex-start will align the items at the top of the screen, flex-end will align the items at the bottom, and space-between will maximize the distance between items (i.e., box 1 will be at the very top of the screen, box 3 at the bottom, and box 2 centered).

Using alignItems

alignItems determines how an item should be rendered along the secondary axis, which is determined by the flexDirection property. This is the inverse of justifyContent. So, if justifyContent is handling the vertical alignment, then alignItems is handling the horizontal alignment.

Available values: flex-start, flex-end, center, and baseline.

Below, we see how alignItems can be used to center the content horizontally when using the default flexDirection (column).

import React from "react";
import { StyleSheet, View } from "react-native";

export default function App() {
  return (
    <>
      <View style={styles.container}>
        <View style={styles.square} />
        <View style={styles.square} />
        <View style={styles.square} />
      </View>
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#7CA1B4",
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  square: {
    backgroundColor: "#7cb48f",
    width: 100,
    height: 100,
    margin: 4,
  },
});

Align Items Property Creating Horizontal Group Of Three Squares On The Center Of Mobile Screen

Likewise, when setting the alignItems to flex-end, we see that the elements move to the end of the flex area, the far right.

import React from "react";
import { StyleSheet, View } from "react-native";

export default function App() {
  return (
    <>
      <View style={styles.container}>
        <View style={styles.square} />
        <View style={styles.square} />
        <View style={styles.square} />
      </View>
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#7CA1B4",
    flex: 1,
    justifyContent: "center",
    alignItems: "flex-end",
  },
  square: {
    backgroundColor: "#7cb48f",
    width: 100,
    height: 100,
    margin: 4,
  },
});

Flex End Property Creating Horizontal Group Of Three Squares On The Right Side Of Mobile Screen

Using alignSelf

alignSelf determines how a child should align itself, and it overrides alignItems. The available values for alignSelf are flex-start,flex-end,center,baseline.

Below, we set a default alignItems property and then override it using alignSelf.

import React from "react";
import { StyleSheet, View } from "react-native";

export default function App() {
  return (
    <>
      <View style={styles.container}>
        <View style={styles.square} />
        <View style={[styles.square, { alignSelf: "flex-end" }]} />
        <View style={[styles.square, { alignSelf: "flex-start" }]} />
      </View>
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#7CA1B4",
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  square: {
    backgroundColor: "#7cb48f",
    width: 100,
    height: 100,
    margin: 4,
  },
});

Here’s what it looks like:

Align Self Property Overriding Align Items To Create A Square In The Center, And On The Left And Right Sides Of Mobile Screen

Building a Flexbox grid

Now that we know what each property in Flexbox does, let’s create a grid using Flexbox. Our end goal is what you see in the next image. Feel free to take the starter code and try it yourself before following along.

Three By Three Grid Containing Letters "A" Through "I" On Mobile Screen

// starter.js

import React from "react";
import { StyleSheet, View, Text } from "react-native";

export default function App() {
  return <View style={styles.container}></View>;
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#7CA1B4",
    alignItems: "center",
    justifyContent: "center",
  },
});

Looking at the example image, we can break it down so that we have three rows each with its own three columns. Each square should render its text vertically and horizontally.

I’m going to create a Square component to save on some repetition:

import React from "react";
import { StyleSheet, View, Text } from "react-native";

const Square = ({ text }) => (
  <View style={styles.square}>
    <Text style={styles.text}>{text}</Text>
  </View>
);

export default function App() {
  return (
    <View style={styles.container}>
      <View style={styles.row}>
        <Square text="A" />
        <Square text="B" />
        <Square text="C" />
      </View>
      <View style={styles.row}>
        <Square text="D" />
        <Square text="E" />
        <Square text="F" />
      </View>
      <View style={styles.row}>
        <Square text="G" />
        <Square text="H" />
        <Square text="I" />
      </View>
    </View>
  );
}

Letters "A" Through "I" Displayed Horizontally On The Center Of Mobile Screen

We’ve added a few style properties here, namely styles.row and styles.square.

We know the row should render its items in a row, so let’s set its flexDirection: 'row'.

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#7CA1B4",
    alignItems: "center",
    justifyContent: "center",
  },
  row: {
    flexDirection: "row",
  },
});

Flex Direction Row Property Stacking Letters A,B,C, On Top Of Letters D,E,F, On Top Of Letters G,H,I In Center Of Mobile Screen

Next, we’ll create the square itself with the appropriate border, height and width, and text color. We can then use justifyContent and alignItems on that square to vertically and horizontally center the text within it. Check it out:

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#7CA1B4",
    alignItems: "center",
    justifyContent: "center",
  },
  row: {
    flexDirection: "row",
  },
  square: {
    borderColor: "#fff",
    borderWidth: 1,
    width: 100,
    height: 100,
    justifyContent: "center",
    alignItems: "center",
  },
  text: {
    color: "#fff",
    fontSize: 18,
    fontWeight: "bold",
  },
});

Three By Three Grid Containing Letters "A" Through "I" on Mobile Screen

This leaves us with the final code:

// finished.js

import React from "react";
import { StyleSheet, View, Text } from "react-native";

const Square = ({ text }) => (
  <View style={styles.square}>
    <Text style={styles.text}>{text}</Text>
  </View>
);

export default function App() {
  return (
    <View style={styles.container}>
      <View style={styles.row}>
        <Square text="A" />
        <Square text="B" />
        <Square text="C" />
      </View>
      <View style={styles.row}>
        <Square text="D" />
        <Square text="E" />
        <Square text="F" />
      </View>
      <View style={styles.row}>
        <Square text="G" />
        <Square text="H" />
        <Square text="I" />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#7CA1B4",
    alignItems: "center",
    justifyContent: "center",
  },
  row: {
    flexDirection: "row",
  },
  square: {
    borderColor: "#fff",
    borderWidth: 1,
    width: 100,
    height: 100,
    justifyContent: "center",
    alignItems: "center",
  },
  text: {
    color: "#fff",
    fontSize: 18,
    fontWeight: "bold",
  },
});

If you’re interested in a slightly more complex example that uses a FlatList, which makes it scrollable, I’ve covered that topic over on React Native School.

Designing a Flexbox card

Next let’s try to build a card layout using Flexbox. Again, feel free to take the starter code and try it on your own first.

// start.js
import React from "react";
import { StyleSheet, View, Text, Image, Dimensions } from "react-native";

export default function App() {
  return (
    <View style={styles.container}>
      <View>
        <View>
          <Text style={styles.nameText}>React Native School</Text>
          <Text style={styles.followText}>Follow</Text>
        </View>
        <Image
          style={styles.image}
          resizeMode="cover"
          source={{
            uri:
              "<https://images.pexels.com/photos/3225517/pexels-photo-3225517.jpeg?cs=srgb&dl=pexels-michael-block-3225517.jpg&fm=jpg>",
          }}
        />
        <View>
          <Text>
            <Text style={styles.nameText}>{`React Native School `}</Text>
            This has been a tutorial on how to build a layout with Flexbox. I
            hope you enjoyed it!
          </Text>
        </View>
      </View>
    </View>
  );
}

const screen = Dimensions.get("screen");
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#7CA1B4",
  },
  image: {
    height: screen.width * 0.8,
  },
  nameText: {
    fontWeight: "bold",
    color: "#20232a",
  },
  followText: {
    fontWeight: "bold",
    color: "#0095f6",
  },
});

Let’s get the card and container situated first. First, we horizontally and vertically align the card. We also set a width for the card to be 80% of the screen’s width, like so:

export default function App() {
  return (
    <View style={styles.container}>
      <View style={styles.card}>
        {/* ... */}
      </View>
    </View>
  );
}

const screen = Dimensions.get("screen");
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#7CA1B4",
    alignItems: "center",
    justifyContent: "center",
  },
  card: {
    backgroundColor: "#fff",
    width: screen.width * 0.8,
  },
  image: {
    height: screen.width * 0.8,
  },
  nameText: {
    fontWeight: "bold",
    color: "#20232a",
  },
  followText: {
    fontWeight: "bold",
    color: "#0095f6",
  },
});

Card Image Of River And Mountains With Text On The Header And Footer Displayed In The Center Of Mobile Screen

Now let’s handle the header. We want the text to render in a single line and “stick” to each edge. We can accomplish this by defining the flexDirection and justifyContent. We’ll also set some vertical and horizontal padding.

import React from "react";
import { StyleSheet, View, Text, Image, Dimensions } from "react-native";

export default function App() {
  return (
    <View style={styles.container}>
      <View style={styles.card}>
        <View style={styles.header}>
          <Text style={styles.nameText}>React Native School</Text>
          <Text style={styles.followText}>Follow</Text>
        </View>
        {/* ... */}
      </View>
    </View>
  );
}

const screen = Dimensions.get("screen");
const styles = StyleSheet.create({
        // ...
  header: {
    flexDirection: "row",
    justifyContent: "space-between",
    paddingHorizontal: 15,
    paddingVertical: 10,
  },
});

Card With Increased Header Space Stating "React Native School" And "Follow" On The Same Line

Finally, the footer. All we need to do here is set the padding! Why is that? Because we’ve nested our Text components and applied styling to the name part so we don’t need to worry about the layout here. Work smarter, not harder! Here’s the final result:

// finished.js

import React from "react";
import { StyleSheet, View, Text, Image, Dimensions } from "react-native";

export default function App() {
  return (
    <View style={styles.container}>
      <View style={styles.card}>
        <View style={styles.header}>
          <Text style={styles.nameText}>React Native School</Text>
          <Text style={styles.followText}>Follow</Text>
        </View>
        <Image
          style={styles.image}
          resizeMode="cover"
          source={{
            uri:
              "<https://images.pexels.com/photos/3225517/pexels-photo-3225517.jpeg?cs=srgb&dl=pexels-michael-block-3225517.jpg&fm=jpg>",
          }}
        />
        <View style={styles.footer}>
          <Text>
            <Text style={styles.nameText}>{`React Native School `}</Text>
            This has been a tutorial on how to build a layout with Flexbox. I
            hope you enjoyed it!
          </Text>
        </View>
      </View>
    </View>
  );
}

const screen = Dimensions.get("screen");
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#7CA1B4",
    alignItems: "center",
    justifyContent: "center",
  },
  card: {
    backgroundColor: "#fff",
    width: screen.width * 0.8,
  },
  header: {
    flexDirection: "row",
    justifyContent: "space-between",
    paddingHorizontal: 15,
    paddingVertical: 10,
  },
  image: {
    height: screen.width * 0.8,
  },
  footer: {
    paddingHorizontal: 15,
    paddingVertical: 10,
  },
  nameText: {
    fontWeight: "bold",
    color: "#20232a",
  },
  followText: {
    fontWeight: "bold",
    color: "#0095f6",
  },
});

Card With Increased Footer Space Stating "React Native School This has been a tutorial on how to build a layout with Flexbox. I hope you enjoyed it!"

And that’s an introduction to using Flexbox in React Native to build layouts! Flexbox is a dynamic and powerful tool that fits perfectly into the mobile environment.

To learn more about some more obscure properties, check out React Native’s documentation.

: Full visibility into your web 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 apps.

Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.https://logrocket.com/signup/

LogRocket is like a DVR for web apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web apps — .

.
Spencer Carli Spencer is a fullstack developer primarily building cross-platform apps with React Native and teaching others to do the same at React Native School.

Leave a Reply