45

enter image description here

I have 6 View components (shown in the picture) , I want to have space between all 6 View components.

My code:

<View style={{flexDirection:'column',flex:6}}>
            <View style={{flex:2,flexDirection:"row",justifyContent:'space-between'}}>
                <View style={{backgroundColor:'red',flex:1}}>
                </View>
                <View style={{backgroundColor:'blue',flex:1}}>
                </View>
            </View>


            <View style={{flex:2,flexDirection:"row",justifyContent:'space-between'}}>
                <View style={{backgroundColor:'white',flex:1}}>
                </View>
                <View style={{backgroundColor:'black',flex:1}}>
                </View>

            </View>

            <View style={{flex:2,flexDirection:"row",justifyContent:'space-between'}}>
                <View style={{backgroundColor:'gray',flex:1}}>
                </View>
                <View style={{backgroundColor:'yellow',flex:1}}>
                </View>

            </View>


 </View>
Behdad
  • 1,459
  • 3
  • 24
  • 36

16 Answers16

50

Try to add padding to the element then and another blank view in each row, padding make space between each item

enter image description here

<View style={{
      flexDirection:'column',
      flex:1,
    }}>
        <View style={{flex:2,flexDirection:"row",justifyContent:'space-between',padding:10}}>
            <View style={{backgroundColor:'red',flex:2,padding:10}}>
            </View>
          <View style={{flex:0.1}}/>
            <View style={{backgroundColor:'blue',flex:2,padding:10}}>
            </View>
        </View>

        <View style={{flex:2,flexDirection:"row",justifyContent:'space-between',padding:10}}>
            <View style={{backgroundColor:'white',flex:2,padding:10}}>
            </View>
            <View style={{flex:0.1}}/>
            <View style={{backgroundColor:'black',flex:2,padding:10}}>
            </View>
      </View>
      <View style={{flex:2,flexDirection:"row",justifyContent:'space-between',padding:10}}>
            <View style={{backgroundColor:'gray',flex:1,padding:10}}>
            </View>
            <View style={{flex:0.1}}/>
            <View style={{backgroundColor:'yellow',flex:1,padding:10}}>
            </View>
        </View>
JeffreyChong
  • 167
  • 1
  • 2
  • 11
Maulana Prambadi
  • 1,015
  • 9
  • 7
32

As of React Native 0.71.0, you can use the gap property. These child views will have a gap of 10 pixels between each row / column.

<View style={{flexDirection:'column', gap: 10 }}>
  <View />
  <View />
  <View />
  <View />
  <View />
  <View />
</View>
Matthew Dean
  • 658
  • 7
  • 9
12

You can simply add margins to the elements and it will work fine. enter image description here

<View style={{flexDirection:'column',flex:6}}>
  <View style={{flex:2,flexDirection:"row",justifyContent:'space-between', marginBottom: 10}}>
    <View style={{backgroundColor:'red',flex:1, marginRight: 5}}>
    </View>
    <View style={{backgroundColor:'blue',flex:1, marginLeft: 5}}>
    </View>
  </View>


  <View style={{flex:2,flexDirection:"row",justifyContent:'space-between', marginBottom: 10}}>
    <View style={{backgroundColor:'white',flex:1, marginRight: 5}}>
    </View>
    <View style={{backgroundColor:'black',flex:1, marginLeft: 5}}>
    </View>
  </View>

  <View style={{flex:2,flexDirection:"row",justifyContent:'space-between', marginBottom: 10}}>
    <View style={{backgroundColor:'gray',flex:1, marginRight: 5}}>
    </View>
    <View style={{backgroundColor:'yellow',flex:1, marginLeft: 5}}>
    </View>
  </View>
</View>
Tarik Fojnica
  • 665
  • 6
  • 15
10

If you are using the map function to render your components, you can try the following code:

// Change to the number of columns in your grid
const numCols = 4;

// Change to the spacing for each item
const spacing = '1.25rem';

// Parent View
<View style={{
    flex: 1,
    flexDirection: 'row',
    flexWrap: 'wrap',
  }}
>
{// List of child views to render
contents.map((content, index) => (
    // add a margin of 'spacing' to the bottom of all cards
    // will supply a left-margin to all cards in between the gap,
    // everytime a card is NOT divisible numCols, add a margin to the left
    <View style={{
      marginBottom : spacing,
      marginLeft: index % numCols !== 0 ? spacing : 0 
    }}
    >
    <Card 
      key={index}
      content={content}
      />
    </View>
  ))
}
</View>

I found that using the following code snippet will create an effect similar to gap in css grids.

enter image description here

ezennnn
  • 1,239
  • 11
  • 13
  • 1
    can you alter it so that the marginBottom is also 0 when it is the last row? – Archimedes Trajano Aug 11 '21 at 19:11
  • Can you show the full code? It's not clear to me how you ensure it gets 4 columns unless you divide the container width by 4 and limit each Card to that width. Also your numCols says 4 but the graphic shows 3. I like your solution, but I don't think it's complete – wongz Dec 15 '21 at 19:54
4

Give the following styling to the parent container (Block/View).

  justifyContent: 'space-around'

OR

  justifyContent: 'space-between'

Space-around will put space between all the elements/view/items and also add space to the borders. Same as all elements get the margin. And the space-between will put the space between all items, without adding space to the borders All this stuff is explained here beautifully. Here is the link

Arslan
  • 240
  • 3
  • 9
  • 1
    But this will justify the content to center. It would't work if you would want the items to be left aligned with trailing white space. – Matt Yoon Jul 22 '21 at 08:57
4

UPDATE: As of react-native 0.71.0 you can use the gap property directly in the styles Refer: https://reactnative.dev/blog/2023/01/12/version-071#simplifying-layouts-with-flexbox-gap

Try this

const Component = () => {
  return (
    <View style={styles.container}>
      <View style={styles.child}></View>
      <View style={styles.child}></View>
    </View>
  );
};

// Gap you want to achieve
const gap = 8;

const styles = StyleSheet.create({
  container: {
    flexDirection: "row",
    paddingHorizontal: (gap / -2),
  },
  child: {
    marginHorizontal: gap / 2,
  },
});
Hashim pk
  • 284
  • 2
  • 9
2

For me, the solution, among using justify-content: 'space-between', was to explicitly give width to the parent view (in my case, width: '100%'), otherwise, 'space-between' didn't do anything.

Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
1

you have 2 solutions in this case

first, use margin/padding for make air between flex element

and the other way is set justifyContent to 'space-between' || 'space-around'

but you must know about some information to use the best solution in a different case

1- (margin-padding)

in some case (more case), padding better margin

as you know, if we have a box ( means element ), you have two space,

first between content and border [ Inner space ]

second, space between the border and another foreign box element [ outer space ]

if you have an element and you want move element in your style you must use margin, because if you use padding for your element, inner space changed and in many cases, this approach creates some crash in your element, {{ if you want to use padding you must create one View and wrap all of your element and set the padding for a wrapper for you }}

and if you want to use space-between || space-around, you must know this, space-between and space-around have one diff

in space-between, space produced between elements and not create space between your element with sides

and space-around set space with elements and with sides

Ashad Nasim
  • 2,511
  • 21
  • 37
hamidreza nikoonia
  • 2,007
  • 20
  • 28
1

You can give the parent a negative margin in the same direction you use on the children.

const Comp: FC = () => {

  return (
    <View style={styles.container}>
      <View style={styles.item}></View>
      <View style={styles.item}></View>
      <View style={styles.item}></View>
      <View style={styles.item}></View>
    </View>
  )
}

const styles = StyleSheet.create({
  item: {
    // Just for visual representation:
    borderWidth: 2,
    borderColor: '#FF0000',
    height: 100,

    // Important styles:
    marginRight: 15,
    flexBasis: '40%',
    flexGrow: 1,
  },
  container: {
    // Important styles:
    marginRight: -15,
    flexDirection: 'row',
    flexWrap: 'wrap',
  },
});

export default Comp;
MauriceNino
  • 6,214
  • 1
  • 23
  • 60
1

If you want to put some vertical space, without flex, this is simple (just for temporary use)

enter image description here

Rahul Sarma
  • 763
  • 2
  • 8
  • 17
0
<View style={{ flexDirection: "row", flexWrap: "wrap" }}>
          {Array(30)
            .fill({ name: "product name" })
            .map((item, key, arr) => (
              <View
                key={key}
                style={{
                  height: 200,
                  paddingTop: 15,
                  backgroundColor: "skyblue",
                  ...(key % 2 !== 0
                    ? { paddingRight: 15, paddingLeft: 15 }
                    : { paddingLeft: 15 }),
                  flexBasis: "50%",
                }}
              >
                <View
                  style={{
                    flex: 1,
                    backgroundColor: variables?.BackgroundLight,
                  }}
                >
                  <Text style={styles && { ...styles?.text }}>{item.name}</Text>
                </View>
              </View>
            ))}
        </View>

Try this out. You can better control it using array map

0

We can achieve the gap between the childrens by wrapping this component

import { StyleSheet, View } from 'react-native';
import React from 'react';
import PropTypes from 'prop-types';

import { normalize } from '../../utils/responsiveSizes';

const VerticalSpace = ({ children, gap = normalize(8), style }) => {
  if (!children) {
    return null;
  }

  if (children && !children?.length) {
    return children;
  }

  const getPaddingBottom = (index) => {
    if (children.length === index + 1) {
      return 0;
    }
    return gap;
  };

  return (
    <View style={[styles.container, style]}>
      {children?.map((child, index) => (
        <View key={index} style={{ paddingBottom: getPaddingBottom(index) }}>
          {child}
        </View>
      ))}
    </View>
  );
};

VerticalSpace.propTypes = {
  children: PropTypes.node.isRequired,
  gap: PropTypes.number,
  style: PropTypes.object,
};

export default VerticalSpace;

const styles = StyleSheet.create({
  container: {
    flexDirection: 'column',
  },
});

And you can use the VerticalSpace component like this

import { StyleSheet, View } from 'react-native';
import React from 'react';
import PropTypes from 'prop-types';

import { normalize } from '../../utils/responsiveSizes';

const App = ({ children, gap = normalize(8), style }) => {

  return (
    <VerticalSpace>
      <Children1/>
      <Children2/>
      <Children3/>
      ...
    </VerticalSpace>
  );
};


export default App;
0

For FlatList or ScrollView:

Pass it through contentContainerStyle instead of style.

<FlatList
  style={styles.listContainer}
  contentContainerStyle={styles.list}

  keyExtractor={({ id }) => id}
  data={[/* ... */]}
  renderItem={({ item: { name } }) => (
    <View style={styles.card}>
      <Text>{name}</Text>
    </View>
  )}
/>

// ...
const styles = StyleSheet.create({
  listContainer: {
    width: "100%",
    backgroundColor: "blue",
  },
  list: {
    gap: 4,
    backgroundColor: "red",
  },
  card: {
    padding: 8,
    flexDirection: "row",
    backgroundColor: "green",
  },
});

rendered screen

Lucas Caton
  • 3,027
  • 1
  • 24
  • 34
0

enter image description here

Soltuon1:

if you are using React native >= 0.71 version, you can use gap, rowGap, columnGap <=Reference

like this

<View 
style={{ flexDirection:'row', gap: 10 }}
>

OR

<View 
style={{ flexDirection:'row', rowGap: 10, columnGap: 10 }}
>

Solution 2:

If you are using React native < 0.71 then you can wrap your component within View and then you can pass padding into parent view by checking the loop index, like this

renderItem={({item, index}) => {
  return (
    <View style={{paddingRight:index%2===0?0:10}}>
      <YourComponent />
    </View>
  );
}}
Muhammad Numan
  • 23,222
  • 6
  • 63
  • 80
-1

        <View style={{flex:2,flexDirection:"row",flexWrap: 'wrap'}}>
            <View style={{backgroundColor:'white',flex:1,marginHorizontal:5,marginVertical:10,}}>
            </View>
            <View style={{backgroundColor:'black',flex:1,marginHorizontal:5,marginVertical:10,}}>
            </View>

        </View>

        <View style={{flex:2,flexDirection:"row",flexWrap: 'wrap'}}>
            <View style={{backgroundColor:'gray',flex:1,marginHorizontal:5,marginVertical:10,}}>
            </View>
            <View style={{backgroundColor:'yellow',flex:1,marginHorizontal:5,marginVertical:10,}}>
            </View>

        </View>

nanthu
  • 9
  • 2
-3

You can add the following in your style:

attachcontainer{
   flexDirection:  'row',
   justifyContent: 'space-between'
}
fedorqui
  • 275,237
  • 103
  • 548
  • 598
James Siva
  • 1,243
  • 1
  • 14
  • 19