React Native Stylesheet: what does {flex:1} do?

FlexboxReact Native

Flexbox Problem Overview


React Native uses flexbox for layout. In all of the examples I've seen, they do something like this:

var styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row'
  }
});

I'm curious about the flex: 1 part. Based on Chris Coyier's definition here https://css-tricks.com/snippets/css/a-guide-to-flexbox/, flex: 1 should be the same as flex-grow: 1, but to me it looks like flex: 1 in React Native is equivalent to display: flex in CSS.

Here's a CodePen that demonstrates that flex: 1 the way React Native examples use it doesn't do anything in CSS:

http://codepen.io/johnnyo/pen/BoKbpb

It's not until we use display: flex in CSS until flexbox starts to work:

http://codepen.io/johnnyo/pen/epZXgz

So does this mean that flex: 1 in React Native is equivalent to display: flex in CSS?

Flexbox Solutions


Solution 1 - Flexbox

There is quite a difference between css flexbox and the one implemented by Facebook. Lots of things in common but defaults are very different. Specifically:

Everything is display: flex by default. All the behaviors of block and inline-block can be expressed in term of flex but not the opposite.

flex: attribute is only used when at the same level there are few components with different flex values (flex: 1, flex: 3) means that the second element should be 3 times bigger than the first one. flex attribute is the only one supported (no grow/shrink support).

More info: https://github.com/facebook/css-layout

Solution 2 - Flexbox

A remark to Jarek Potiuk's answer: 'flex: 1' does do something in react-native similar to flex-grow behavior. Even if it is the only one with flex: defined.

Styles such as flexDirection, alignItems, justifyContent all define styling of children of the element. Similar to CSS Display: flex, which also defines children.

In contrast, flex: x defines the element itself.

E.g. if a container component has flexDirection: 'row', alignItems: 'center'
And there are 3 children:

> child 1 has width 50 > > child 2 has flex 1 (or any other number, but 1 is common practice) > > child 3 has width 50

Then the middle component will 'stretch' so that the 3 children together fill the entire width of the parent component.

Solution 3 - Flexbox

A lot of tutorials use flex: 1, much like as you did in your example. The main reason is because sometimes (depending on the element, such as ListStyle by default, if my memory serves) the component will not take up the entire screen/area if you do not define the dimensions, such as the height (eg. height: '400px'). Flex: is awesome because it keeps things responsive for various sizes.

But I should note that for any component with no siblings, the value for flex is totally arbitrary. Ex. for your top-level component, you could say flex: 43254315 and it does the same thing as flex: 1. It just means "take up the entire space" (whatever "entire" that may be).

On the other hand, if you have some sibling components, then the flex value matters a lot. For example, if one component is flex: 2 and another is flex: 3, then the first takes up 2/5 of the screen and the second takes up 3/5 of the screen.

In short: Depending on your styles, it might look like flex: 1 is the same as display: flex, but that's only because of the way you are using it in your example. You'll see it act very differently if you just give it some siblings.

Solution 4 - Flexbox

Like you I struggled to understand this tag that isn't documented properly on Facebook Code, but I eventually discovered that it does two things:

  1. Containers consider any children with a flex attribute to have a height of 0 for the purpose of determining how much space they take up.
  2. Components with flex: X expand to take up any room remaining in their container after other components have been laid out. They share this extra space in proportion with their X values.

The first item is why flex: 1 can appear to have the same effect as display: flex. Consider the following JSX code:

<ExampleAppContainer>
    <Text>
        I get printed.
    </Text>
    <Text style={{flex: 1}}>
        But I don't :(
    </Text>
</ExampleAppContainer>

Only the first text component gets printed, because the second one is considered to have a height of 0. ExampleAppContainer allocates enough space for the first text component, and there isn't any room for the second one to expand.

Now consider this code:

<ExampleAppContainer style={{flex:1}}>
    <Text>
        I get printed.
    </Text>
    <Text style={{flex: 1}}>
        And so do I!
    </Text>
</ExampleAppContainer>

Since ExampleAppContainer has flex: 1, it expands to take up as much room as it can. Assuming that it is the root component for the React part of your app, this is usually going to be the entire phone screen. Next it allocates sufficient space for the first text component, and allows the second text component to expand, taking up the rest of the screen.

In this fashion you will often need to apply flex: 1 all the way down you component hierarchy in order to allow your innermost components with flex: N room to expand properly.

Solution 5 - Flexbox

flex: 1
  1. Tells a component to fill all available space (shared amongst other components with the same parent).

  2. If there are sibling components with flex values, their parent needs to have flex: 1 (or higher). If a parent does not have either a fixed width and height or flex, the parent will have dimensions of 0 and the flex children will not be visible.

Solution 6 - Flexbox

this is very simple just think that when you say flex: 1 to any elements that element get all height of parent element if this element have flex: 1 and dont have parent element get all height of screen size.

for example you want have one container element that get all height of screen and this element have three child element that each element have 1/3 height of screen for this example just get the parent element flex: 1 and three child element flex: 1/3 see code bellow

<View style={{flex: 1,backgroundColor: 'red'}}>

        <View style={{flex: 1/3, backgroundColor: 'green'}}></View>

        <View style={{flex: 1/3, backgroundColor: 'yellow'}}></View>

        <View style={{flex: 1/3, backgroundColor: 'pink'}}></View>

      </View>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohnny OshikaView Question on Stackoverflow
Solution 1 - FlexboxJarek PotiukView Answer on Stackoverflow
Solution 2 - FlexboxwintveltView Answer on Stackoverflow
Solution 3 - FlexboxRyo-codeView Answer on Stackoverflow
Solution 4 - FlexboxPeter Evan DealView Answer on Stackoverflow
Solution 5 - FlexboxFellow StrangerView Answer on Stackoverflow
Solution 6 - Flexboxhamidreza ghanbariView Answer on Stackoverflow