90

I was wondering there is a way I can align vertically in React Native. I'm trying to position on the bottom but I don't think I can find a good way to do it.

If anyone knows how to solve this issue, please let me know.

AmerllicA
  • 29,059
  • 15
  • 130
  • 154
ckim16
  • 1,569
  • 3
  • 19
  • 30

12 Answers12

96

You can use the flex property, justifyContent to achieve this. Full documentation here.

<View style={{justifyContent: 'center'}}>
   <Text>Vertically Centered Text</Text>
</View>
Greg Billetdeaux
  • 2,039
  • 13
  • 9
  • I think this is the best approach due to limitations on the Text components. of course you will need to play with `justifyContent` and `alignItems` to get your optimal result. – Wiston Coronell Dec 09 '21 at 15:18
90

to align any content including text both horizontally and vertically, simply use the following in the container which holds it

    container :{
       justifyContent: 'center', //Centered vertically
       alignItems: 'center', //Centered horizontally
       flex:1
    }
JasperMW
  • 465
  • 3
  • 7
  • 22
Haseeb A
  • 5,356
  • 1
  • 30
  • 34
40

You can use an android-only style property textAlignVertical

To align text on top:

style={{textAlignVertical: 'top'}}

To align text on center:

style={{textAlignVertical: 'center'}}

To align text on bottom:

style={{textAlignVertical: 'bottom'}}
panoptical
  • 782
  • 1
  • 8
  • 22
Roman
  • 19,236
  • 15
  • 93
  • 97
  • 17
    The `textAlignVertical` style is an Android-only property. If you are developing on iOS, try using the flexbox alignment property `alignItems: center` instead. see also [textAlignVertical is not valid](https://stackoverflow.com/questions/34969848/textalignvertical-is-not-a-valid-style-property). – Top-Master May 21 '19 at 06:50
  • I recommend you don't use this. Go with solutions that work cross platform. – Sigex Jan 12 '21 at 10:39
12

This problems occurs especially when you are using image or icon. I had a same problem my solution:

 <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center' }}>
   <Icon type="MaterialCommunityIcons" name="barcode" />
   <Text style={{ textAlign: 'center' }}>{urun_data.barkod}</Text>
</View>
Berkay Kaan
  • 295
  • 3
  • 10
11

I had a similar problem and looked at many of the other posts here. Here is what worked for me.

I created an initial view, and nested the elements I wanted vertically centered within that view. I made the mistake of including 'flex: 1' in the initial view, which screwed up the vertical alignment.

The code:

<View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center'}}>
  <Text>Content here to be vertically aligned</Text>
  <Switch>...</Switch>
</View>
FontFamily
  • 355
  • 4
  • 13
  • I don't think you would need the `flexDirection: 'row'`. The default flex direction is row already. Also, you probably want to add `flex: 1` to the View so it covers the full view height. – aaronmbmorse Jan 24 '21 at 06:20
5

RN version >= 0.55.2 is support to "textAlignVertical" now.

<TextInput
    style={styles.text}
    onChangeText={text => console.log('text >>>>>>>', text)}
    value='sample text'
 />

text: {
  textAlign: 'center',
  textAlignVertical: 'center',
}

Working with both cases flex: 1 and set height of the <Text> component.

Janaka Pushpakumara
  • 4,769
  • 5
  • 29
  • 34
3

Text vertical center alignment summary

Case 1: There is only one Text under View Ios: Use flex with alignItems/justifyContent to be more centered, Adr: height = lineHeight, includeFontPadding: false more centered

Case 2: There are two Texts in a line view and the two Text fonts are different, and the Text with a smaller font size does not need to use the height.

The larger one is aligned using the above method. The smaller one can only be used with font-size, but not with the line-height and height attributes. In this case, both texts can be centered.

Case 3: There are two Texts in a line view and the two Text fonts are different, and the Text with a smaller font size must use the height.

The one with the larger font size is aligned using the above method, and the smaller font size uses height with padding and includeFontPadding to achieve alignment.

And Demo

<View
    style={{
        flexDirection: 'row',
        height: 38,
        borderWidth: 1,
        borderColor: '#000',
        alignItems: 'center'
    }}
>
    <Text
        style={{
            fontSize: 24
        }}
    >
        测试
    </Text>
    <Text
        style={{
            fontSize: 24,
            lineHeight: 36,
            height: 36,
            includeFontPadding: false
        }}
    >
        测试
    </Text>
</View>
<View
    style={{
        flexDirection: 'row',
        height: 38,
        borderWidth: 1,
        borderColor: '#000',
        alignItems: 'center'
    }}
>
    <Text
        style={{
            fontSize: 24
        }}
    >
        ios设备
    </Text>
    <Text
        style={{
            fontSize: 16
        }}
    >
        更对齐
    </Text>
</View>
<View
    style={{
        flexDirection: 'row',
        height: 38,
        borderWidth: 1,
        borderColor: '#000',
        alignItems: 'center'
    }}
>
    <Text
        style={{
            fontSize: 24,
            lineHeight: 36,
            height: 36,
            includeFontPadding: false
        }}
    >
        安卓
    </Text>
    <Text
        style={{
            fontSize: 12,
            height: 18,
            includeFontPadding: false,
            paddingVertical: 2,
            paddingHorizontal: 1,
            paddingTop: DeviceInfo.isIOS ? 3 : 2,
        }}
    >
        更对齐
    </Text>
</View>
tinypoint
  • 31
  • 4
3

The flex: 1 makes the child view take up all the remaining space in the parent view. So remember to make sure the parent is occupying the space it is supposed to.

I would advocate wrapping your content in a <SafeAreaView> tag so that is adjusts content to the device it is in. But you could use any other view type.

 <SafeAreaView style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
     <Text>Centered Text</Text>
 </SafeAreaView>
  • flex: 1 makes the view take up the full width and heigh of the view its in
  • justifyContent: 'center' vertically centers the children
  • alignItems: 'center' horizontally centers the children

You can also use textAlign: center on the Text element and remove the alignItems: 'center'. This of course would only center the text in the Text object and wouldn't work if you had multiple elements that needed to be centered.

aaronmbmorse
  • 359
  • 3
  • 10
1

You can use flexbox with justifyContent: 'flex-end' to achieve vertical centering.

Here's a snack: https://snack.expo.io/@rynek/vertical-centering-with-flexbox-in-react-native

bguiz
  • 27,371
  • 47
  • 154
  • 243
yemd
  • 420
  • 4
  • 15
1

Simply use the alignItems for the vertical alignment

alignItems: 'flex-start' //for start the View : vertical-align: top
alignItems: 'flex-end' // for vertical-align: bottom
alignItems: 'center' // for vertical-align: middle

<View style={{ flexDirection: 'row', alignItems: 'flex-start'}}>
<View>  <Text>hello 1</Text> </View>
<View>  <Text>hello 2</Text> </View>
</View>

Check this example with changing of alignItems

Karthikeyan Ganesan
  • 1,901
  • 20
  • 23
0

Here's a somewhat ugly solution to the problem. The ScrollView will take up the remaining vertical space, pushing the text down to the bottom.

<View>
  <ScrollView>{}</ScrollView>
  <Text>Your text</Text>
</View>

Or..

<View>
  <View style={{ flex: 1 }}>{}</View>
  <Text>Your text</Text>
</View>
Amsvartner
  • 733
  • 7
  • 19
0

use flex:1 property on both as on container of the Text component and itself inside the Text component.Because if u don't define the height and width its not working.

  <View style={{
     flex:1,
        }} >  
     <Text style={{
       flex:1,
       color: COLORS.primary,
       fontFamily: "FredokaOne-Regular",
       fontSize:40,
       textAlign:"center",
       textAlignVertical:"center",
       }}
     numberOfLines={2} >
       Travia War
     </Text>
  </View>
U13-Forward
  • 69,221
  • 14
  • 89
  • 114