I'm building an intro slider in React Native using a horizontal FlatList. Each slide consists of:
The problem is that the image and description block stay aligned at the top instead of centering vertically, even though I've applied flex: 1 and justifyContent: 'center'
to their container.
<FlatList
data={slides}
horizontal
pagingEnabled
renderItem={({ item }) => (
<View style={[styles.slide, { width }]}>
<View style={styles.titleContainer}>
<Text style={styles.title}>{item.title}</Text>
</View>
<View style={styles.contentWrapper}>
<item.SlideImage style={styles.image} />
<Text style={styles.desc}>{item.descr}</Text>
</View>
</View>
)}
/>
const styles = StyleSheet.create({
slide: {
flex: 1,
alignItems: 'center',
flexDirection: 'column',
// justifyContent: 'center', // removed to keep title at top
},
titleContainer: {
height: 60,
justifyContent: 'center',
alignItems: 'center',
},
contentWrapper: {
flex: 1,
justifyContent: 'center', // intended to center vertically
alignItems: 'center',
width: '100%',
paddingHorizontal: 20,
},
title: { fontSize: 26, fontWeight: '700', textAlign: 'center' },
image: { width: 300, height: 300 },
desc: { fontSize: 16, textAlign: 'center', marginTop: 12, color: '#555', lineHeight: 22 },
});
I’ve tried several things:
Removing justifyContent: 'center' from slide to keep the title at the top,
Using flexGrow: 1 instead of flex: 1 on contentWrapper,
Setting fixed height or height: '100%' on the slide container,
Making sure the image has fixed width and height.
Outline debugging:
BLUE: container
RED: slide
GREEN: contentWrapper
Still, the content inside contentWrapper stays stuck at the top and won’t center vertically.
Why doesn’t the contentWrapper take all the available vertical space to center its children? How can I fix this layout issue?
To vertically center the image + description block only in the space below the title, you just need to make sure that:
the wrapper that contains the content (contentWrapper
) has flex: 1
, so it takes all the remaining space below the header, and
you use justifyContent: 'center'
to center its children vertically inside that space.
In your code you were already almost there — the only missing piece is that the title container above must not grow (so it doesn’t steal space), while the content wrapper must grow.
<View style={[styles.slide, { width }]}>
<View style={styles.titleContainer}>
<Text style={styles.title}>{item.title}</Text>
</View>
<View style={styles.contentWrapper}>
<item.SlideImage style={styles.image} />
<Text style={styles.desc}>{item.descr}</Text>
</View>
</View>
Now make sure the styles look like this:
titleContainer: {
// DON'T add flex here, or it will take unnecessary space
paddingTop: 40, // your fixed top offset
paddingBottom: 20,
},
contentWrapper: {
flex: 1, // <– grows to fill the rest of the slide
justifyContent: 'center', // <– vertical centering
alignItems: 'center',
paddingHorizontal: 20,
}