3

The Flexbox layout has a property called flex-basis. According to CSS Tricks:

This defines the default size of an element 
before the remaining space is distributed. 
It can be a length (e.g. 20%, 5rem, etc.) or a keyword.

React Native apparently does not support this property. How do I work around this in RN or more specifically, how can I achieve a layout like this:

1, 2, 3, 4 are elements of a list

In that picture, the "1", "2" etc are part of a list and should take roughly 50% of the available space so that 2 elements fit into one row with a bit of margin around them.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
user3346601
  • 1,019
  • 1
  • 11
  • 18

2 Answers2

3

flexBasis property can be used in RN. And yes we can give pixel as well as % values for flexBasis property. Pixel values can be given for this and its straight forward, percentage value can also be given using points like 0.4 defines 40% of the parent.

We can also use Dimensions of RN(import Dimensions from RN), like

const deviceWidth = Dimensions.get('window').width;

and can be used in styling like

const styles = StyleSheet.create({
  parent: {
    width: deviceWidth,
  },
  child: {
    width: deviceWidth * 0.5, // 50% of the parent
  }
});

Similarly like width property used above, we can also give the same values for flexBasis property.

Here is the simple solution for your expected layout.

<View>
    {/* first row */}
    <View style={styles.numbersRow}>
          <Text style={styles.numberText}>1</Text>
          <Text style={styles.numberText}>2</Text>
    </View>
    {/* second row */}
    <View style={styles.numbersRow}>
          <Text style={styles.numberText}>3</Text>
          <Text style={styles.numberText}>4</Text>
    </View>
</View>

styling part:

const styles = StyleSheet.create({
  numbersRow: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-around', // to adjust the spacing
    marginTop: 30,
  },
  numberText: {
    flex: 0.4, // 40% of the parent
    paddingVertical: 30, // 30px padding from top and bottom makes it vertically centered
    borderRadius: 8,
    textAlign: 'center', // horizontally centered
    backgroundColor: '#000',
    color: '#fff',
    fontSize: 30,
  }  
});

Also refer the npm package for better styling https://github.com/vitalets/react-native-extended-stylesheet, includes %, rem units and media queries as well and various features.

Aniruddha Shevle
  • 4,602
  • 4
  • 22
  • 36
0

I am learning React Native and Flexbox too. Your question motivated me to experiment with flex-basis, because I also ran into trouble with it.

I'm using RN 0.34 and running in the iOS simulator.

I found that RN supports "flexBasis" partly. The flexBasis value can only be a number. The number can't be quoted. Qualifiers like '%' or 'px' cause a runtime error.

flexBasis let me control the relative width of Text elements in a row. (It looks like RN interprets the flexBasis value as a percent.) You can see this by running the following code in an RN simulator.

<View >
        <Text>1a) Basic flexBasis</Text>
<View style={{flexDirection: 'row'}}>
    <Text style={{ backgroundColor: "lightgray", flexBasis: 40 }}>foo</Text>
    <Text style={{ backgroundColor: "lightgreen", flexBasis: 20 }}>bar</Text>
    <Text style={{ backgroundColor: "lightblue", flexBasis: 40}}>baz</Text>
</View>

<Text>1b) Basic flexBasis, but with different values and effect than 1a.</Text>
<View style={{flexDirection: 'row'}}>
    <Text style={{ backgroundColor: "lightgray", flexBasis: 10 }}>foo</Text>
    <Text style={{ backgroundColor: "lightgreen", flexBasis: 80 }}>bar</Text>
    <Text style={{ backgroundColor: "lightblue", flexBasis:10}}>baz</Text>
</View>

<Text>2) Adding flexGrow makes the items fill the row.</Text>
<View style={{flexDirection: 'row'}}>
    <Text style={{ backgroundColor: "lightgray", flexGrow: 1, flexBasis: 10 }}>foo</Text>
    <Text style={{ backgroundColor: "lightgreen", flexGrow: 2, flexBasis: 80 }}>bar</Text>
    <Text style={{ backgroundColor: "lightblue", flexGrow: 1, flexBasis:10}}>baz</Text>
</View>

<Text>3) Flexbox attirbutes spaceBetween and spaceAround didn't work. But CSS margin can separate the items.</Text>
<View style={{flexDirection: 'row'}}>
    <Text style={{ backgroundColor: "lightgray", marginRight: 10, flexGrow: 1, flexBasis: 10 }}>foo</Text>
    <Text style={{ backgroundColor: "lightgreen", flexGrow: 2, flexBasis: 80 }}>bar</Text>
    <Text style={{ backgroundColor: "lightblue", marginLeft: 10, flexGrow: 1, flexBasis:10}}>baz</Text>
</View>
</View>

In other blog posts, I saw examples of people rounding element corners by using borderRadius. But when I tried their code, I didn't end up with rounded corners.

Probably the original poster already found an answer. Perhaps another RN newbie will find this info helpful.

devdanke
  • 1,309
  • 15
  • 27
  • **RN does not actually run the CSS, it's JS is what runs behind the scenes.** Hence the % or px does not count in RN for styling purposes yet. And also CSS keywords like auto, inherit, initial, etc will not be counted in RN for styling purposes. **But yes % values can be achievable please refer my answer** for this question [link](http://stackoverflow.com/questions/35436478/react-native-substitute-for-flex-basis/43022365#43022365). – Aniruddha Shevle Mar 25 '17 at 22:18