React Native Layout Tricks

React Native Layout Tricks

The basics of positioning are pretty well explained in the official React Native documentation.

However, it only covers simple cases such as centering items or putting one element on top, middle and bottom.
Here I intend to cover some cases that are quite common but for which I couldn’t find a suitable documentation.

One item centered and one on the right, none on the left

N.B.: All of the following also works the other way around, or with top and bottom instead of left and right if you use flexDirection: column on the container.

If you know the width of the item on the right

native_size_known

export default class reactNativePositionning extends Component {
  render() {
    return (
      {/* Container */}
      <View style={{
        flexDirection: 'row',
        justifyContent: 'space-between',
      }}>
        {/* empty element on the left */}
        <View style={{ width: 100 }} />
        {/* element in the middle */}
        <View style={styles.box} />
        {/* element on the right */}
        <View style={[styles.box, { width: 100 }]} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  box: {
    backgroundColor: '#927412',
    height: 100,
    width:100,
  },
});

If you don’t know the width of the item on the right

native_unknown_size

If you don’t know the width of the element on the right, you can still wrap every item in another View.
Left and right wrappers will take all the available space, leaving the middle one centered.
The left wrapper will be empty.

export default class reactNativePositionning extends Component {
  render() {
    return (
      {/* Container */}
      <View style={{
        flexDirection: 'row',
        justifyContent: 'space-between',
      }}>

        {/*  empty wrapper */}
        <View style={{
          flexDirection: 'row',
          flex: 1,
        }} />

        {/* element in the middle */}
        <View style={{
          flexDirection: 'row',
          justifyContent: 'center',
        }}>
          <View style={styles.box} />
        </View>

        {/*  element on the right with a different size */}
        <View style={{
          flexDirection: 'row',
          flex: 1,
          justifyContent: 'flex-end',
        }}>
          <View style={[styles.box, { width: 22 }]} />
        </View>

      </View>
    );
  }
}

const styles = StyleSheet.create({
  box: {
    backgroundColor: '#927412',
    height: 100,
    width: 100,
  },
});

Grouping items

native_group

React native still misses margin: auto which is useful for grouping items – you can follow the state of the issue here.

Meanwhile what we can do is adding elements with a flex: 1 property to make them fill the space between blocks.

export default class reactNativePositionning extends Component {
  render() {
    return (
      {/* container */}
      <View style={{
        flexDirection: 'row',
        justifyContent: 'space-between',
      }}>
        {/* element on the left */}
        <View style={styles.box} />
        {/* space */}
        <View style={{ flex: 1 }} />
        {/* elements in the 'middle' */}
        <View style={styles.box} />
        <View style={styles.box} />
        {/* space */}
        <View style={{ flex: 1 }} />
        {/* elements on the right */}
        <View style={styles.box} />
        <View style={styles.box} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  box: {
    backgroundColor: '#927412',
    height: 50,
    marginLeft:2,
    marginRight:2,
    width:50,
  },
});

You can also add the property directly to your elements:

export default class reactNativePositionning extends Component {
  render() {
    return (
      {/* container */}
      <View style={{
        flexDirection: 'row',
        justifyContent: 'space-between',
      }}>
        {/* element on the left */}
        <View style={[styles.box], { flex: 1 }} />
        {/* elements in the 'middle' */}
        <View style={styles.box} />
        <View style={[styles.box], { flex: 1 }} />
        {/* elements on the right */}
        <View style={styles.box} />
        <View style={styles.box} />
      </View>
    );
  }
}