React-native: Setting flex:1 on a ScrollView contentContainerStyle causes overlapping of components

Created on 12 Nov 2015  ·  34Comments  ·  Source: facebook/react-native

I have a ScrollView with 2 subviews and I want the first of them (lets call it ViewA) to have {flex: 1} so the other one (ViewB) will stick to the bottom of the screen - but only if their total height is smaller that the screen. Of course that if they are higher than the screen I want it to scroll as usual.

So I set the ScrollView's style AND contentContainerStyle to be flex: 1. I Also set ViewA's style to flex:1. But when I do it, the ScrollView's contentContainer view is fixed to the screen height, thus not able to scroll if needed and even worse - ViewB overlaps ViewA.

If it's a bug - how to fix it?
If it's the expected behaviour - how can I achieve what I've described?

here's a little demonstration: https://rnplay.org/apps/wZgtWA
Note that even without ViewB, once you set flex:1 on contentContainerStyle you can't scroll the page.

Thanks.

Locked

Most helpful comment

use flexGrow: 1 instead of flex: 1 – works like minheight, much like what you want.

All 34 comments

Try deleting flex: 1 in contentContainerStyle?

@david-a Did you ever get a chance to try @tyliuty suggestion?

@christopherdro I have also been trying this for a while, previously I relied on the minHeight style that was removed in a later version.

I also want the same layout as @david-a (the inner view to stretch to fill if it doesn't, but otherwise continue scrolling); removing the flex:1 from contentContainerStyle means the inner view doesn't fill.

contentContainerStyle work for me! yeah!

I'm having this same issue. I need flex:1 in the contentContainerStyle prop so that the inner view fills the ScrollView when the screen is larger.

This is the layout I have:

<ScrollView style={styles.scrollView} contentContainerStyle={{flex:1}}>
  <View style={styles.container}>
    <View style={styles.bigContainer }>
      <Text>
        Lorem ipsum....//removing the long paragraph for this post
      </Text>
    </View>
    <View style={styles.footerContainer}>
      <Text >
        Cu odio ...
      </Text>
      <Button text="button" />
    </View>
  </View>
</ScrollView>

The styles are:

var styles = StyleSheet.create({
  scrollView:{
    flex:1,
    backgroundColor:'blue'
  },
  container: {
    flex:1,
    paddingTop:65,
    backgroundColor:'pink'
  },
  bigContainer: {
    flex:1,
    padding: 10,
    paddingTop:0
  },
  footerContainer: {
    justifyContent:'flex-end',
    backgroundColor:'yellow'
  },
});

These are the results when I add contentContainerStyle={{flex:1}} to the scrollView.
On iPhone 4s, the bottom container is on top of the top container. I pulled the screen up to take the screenshot and show you how the top view is behind.
simulator screen shot jul 5 2016 4 42 10 pm

on Nexus 7, which is a big phone, it does what I want.
screenshot 2016-07-05 16 46 56

Removing contentContainerStyle={{flex:1}} prevents the content to expand the height of the scrollView for larger devices but scrolls correctly on smaller devices.

on iPhone 4s, the scroll is as expected (see the scrollbar on the side in the screenshot)
simulator screen shot jul 5 2016 4 47 49 pm

on Nexus 7, you can see how the scrollview with blue background extends but the content does not.
screenshot 2016-07-05 16 47 27

@david-a, @ashleydw did you find a solution for this?

I'm having this same issue. I need flex:1 in the contentContainerStyle prop so that the inner view fills the ScrollView when the screen is larger.

I don't think that's possible right now using stylesheet. One thing you might try is getting the height of the scrollview and the inner element, and toggle the styles when inner element is bigger.

Closing this since the original issue is the expected behaviour. Please file a feature request on Product Pains if you want minHeight.

@satya164 as of RN 0.29.0 minHeight is supported. Just wanted to update everyone following this that setting minHeight as a style of the inner container seems to work. You can set the height to the device's height using Dimensions.

For reference: https://github.com/facebook/react-native/commit/78b892906b00932447e86465bec4613c118f01fc

Cool @joelcloralt ! thanks, I'll try that!

I had the similar problem and I solved it using Dimensions and onLayout property as following at least on Android, if there is a better or easier solution please let me know:

   onLayout(e) {
    const {nativeEvent: {layout: {height}}} = e;
    this.height = height;
    this.forceUpdate();
  }

render() {
    const {height: heightOfDeviceScreen} = Dimensions.get('window');
    return (
      <ScrollView contentContainerStyle={{minHeight: this.height || heightOfDeviceScreen}}
                  onLayout={this.onLayout.bind(this)}>
          <View><Text>header</Text></View>
          <View style{{flex: 1}}><Text>body</Text></View>
          <View><Text>footer</Text></View>
      </ScrollView>

Thanks

This problem is similar to what I had. See my answer here: http://stackoverflow.com/a/43912470/3867175

use flexGrow: 1 instead of flex: 1 – works like minheight, much like what you want.

Thank you so much @tanguyantoine!! you saved my day!!

@sarahmarciano You are welcome but why ?

Oh sorry for my mistake @tanguyantoine ! I meant @tushar-singh :)

use flexGrow: 1 instead of flex: 1 – works like minheight, much like what you want.

This works for me. Thank you !

@tushar-singh Worked like a charm! Thanks 👍

@tushar-singh Worked like charm! :+1: Thanks. Have been dealing with this for quiet a long time now!

@tushar-singh excellence, Thanks

@tushar-singh even in my case flexGrow:1 is working, But how come flex:1 is not working which is nothing but short form of flexGrow:1,flexShrink:1,flexBasis:0. Any one explain this pls.

Hello guys,
I have a problem with ScrollView. I have used ScrollView which wrapped a TabNavigator (react-navigation). But when I did that, the content of each tab is hidden. I have tried to set "flexGrow: 1", also "flex: 1" inside contentContainerStyle of ScrollView, the content of tag is showed, but ScrollView is not working. So if those content is long, I cannot see full of content.
Does anyone has the same problem like me?
I need help!

@ravirajn22 in React Native, flex does not work in the same way as CSS, according to its docs: https://facebook.github.io/react-native/docs/layout-props.html

@ravirajn22 Also, on browsers, when you set only flex-grow: 1, you actually get flex-grow:1, flex-shrink:1, flex-basis:auto, since default value of flex-shrink is 1 and default value of flex-basis is auto
In React Native, when you set only flexGrow: 1, you actually get flexGrow:1, flexShrink:0 and flexBasis:'auto', since the default value of flexShrink seems to be 0

@dungle1811 , did you find an answer? i am also facing the same issue yet... if you found an answer tell it to me also..

@tushar-singh Worked like charm! 👍 Thank you very much!!!

@Chathula I have found solution here

if flexGrow doesn't work for you, that's because the parent view must have flex: 1 set

@vinicri which of the container has to have the flewGrow ? The scrollView only? Or the inner containers too ?

Solution as discussed above:
< ScrollView contentContainerStyle={{ flexGrow: 1 }} >
< View style={{ flex: 1 }} >
...
< /View >
< /ScrollView >

UseflexGrow:1its works for me...

@dungle1811 I am facing the same issue. Please provide any solution for this

flexGrow: 1 is not working anymore?

@rendomnet this is working for me: <ScrollView horizontal={true} style={{ flex: 1, flexGrow: 1 }} contentContainerStyle={{ flex: 1 }}> without the contentContainerStyle does not work for me

In case your ScrollView is wrapped within a View, make sure your View has flex: 1 as well.

<View style={{ flex: 1 }}>
  <ScrollView contentContainerStyle={{ flexGrow: 1 }}>
    { ... }
  </ScrollView>
</View>
Was this page helpful?
0 / 5 - 0 ratings