158

It seems that with position:absolute in use an element cannot be centred using justifyContent or alignItems. There's a workaround to use marginLeft but does not display the same for all devices even using dimensions to detect height and width of device.

  bottom: {
    position: 'absolute',
    justifyContent: 'center',
    alignItems: 'center',
    top: height*0.93,
    marginLeft: width*0.18,
  },
  bottomNav: {
    flexDirection: 'row',
  },
David Schumann
  • 13,380
  • 9
  • 75
  • 96
Hasen
  • 11,710
  • 23
  • 77
  • 135

8 Answers8

406

Wrap the child you want centered in a View and make the View absolute.

<View style={{position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, justifyContent: 'center', alignItems: 'center'}}>
  <Text>Centered text</Text>
</View>
David Schumann
  • 13,380
  • 9
  • 75
  • 96
Stephen Horvath
  • 5,188
  • 3
  • 24
  • 31
  • 42
    Very useful. There's a nice shortcut for those style params hanging off of `StyleSheet` object: `...StyleSheet.absoluteFillObject`. see https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/StyleSheet.js#L29 – wkw Mar 04 '17 at 19:35
  • 3
    Doesn't this make the `View` take up ALL clickable space on the screen? E.g if I had a component underneath this absolutely positioned `View`, I wouldn't be able to register clicks on it. – James111 Jan 16 '18 at 04:49
  • 17
    @James111 It looks like you can add `pointerEvents='box-none'` to pass the touches through the view: https://github.com/facebook/react-native/issues/12360 – Stephen Horvath Jan 17 '18 at 10:30
  • This method recovers the entire image if the text has a background color :/ – DevMultiTech Sep 26 '18 at 08:10
  • @codewise yep, there is a new way to do it, check out my answer – David Noreña Jan 02 '19 at 14:13
  • I used this approach to put a ```LoadIndicator``` on top of a component. I also added ```backgroundColor: '#000000AA'``` to the style of the wrapping ```View```. That way, you get a nice grayed look while things are loading. – LGenzelis Nov 27 '19 at 15:46
  • This solution doesn't work when you don't want the absolute container to fill all the space of the parent component for events purposes. The solution with `alignSelf` is best. – kovalyovi Jul 18 '23 at 15:03
130

If you want to center one element itself you could use alignSelf:

logoImg: {
    position: 'absolute',
    alignSelf: 'center',
    bottom: '-5%' // only necessary for my example image
}

This is an example (Note the logo parent is a view with position: relative)

enter image description here

Community
  • 1
  • 1
David Noreña
  • 3,951
  • 1
  • 28
  • 43
20

You can center absolute items by providing the left property with the width of the device divided by two and subtracting out half of the element you'd like to center's width.

For example, your style might look something like this.

bottom: {
    position: 'absolute',
    left: (Dimensions.get('window').width / 2) - 25,
    top: height*0.93,
}
David Schumann
  • 13,380
  • 9
  • 75
  • 96
Corey
  • 1,010
  • 9
  • 17
  • 2
    this only works if you know the elements width beforehand – Adamski Dec 20 '17 at 12:31
  • 3
    If you don't know the element doesn't have a known width you can use onLayout to get the elements width `measure(layout) { const { width } = layout; this.setState({ width: width }) } ... { this.measure(event.nativeEvent.layout) }} ... ` – Corey Dec 20 '17 at 21:18
10

create a full-width View with alignItems: "center" then insert desired children inside.

import React from "react";
import {View} from "react-native";

export default class AbsoluteComponent extends React.Component {
  render(){
    return(
     <View style={{position: "absolute", left: 0, right: 0, alignItems: "center"}}>
      {this.props.children}
     </View>    
    )
  }
}

you can add properties like bottom: 30 for bottom aligned component.

masbossun
  • 291
  • 3
  • 7
6
<View style={{...StyleSheet.absoluteFillObject, justifyContent: 'center', alignItems: 'center'}}>
    <Text>CENTERD TEXT</Text>
</View>

And add this

import {StyleSheet} from 'react-native';
Mahdi Bashirpour
  • 17,147
  • 12
  • 117
  • 144
  • 2
    Short, code-only answers are often frowned upon on Stack Overflow. In order to avoid being flagged as 'low quality', consider adding some explanatory text. – Adrian Mole Oct 30 '19 at 13:06
3

You can try the code

<View
    style={{
      alignItems: 'center',
      justifyContent: 'center'
    }}
  >
    <View
      style={{
        position: 'absolute',
        margin: 'auto',
        width: 50,
        height: 50
      }}
    />
  </View>
David Schumann
  • 13,380
  • 9
  • 75
  • 96
Eris Mabu
  • 111
  • 1
  • 3
  • Haha. This is working for me, However, we need add ` style={{ alignItems: 'center', justifyContent: 'center', flexDirection: 'row' }} ` – babie Aug 29 '19 at 08:27
2

It's very simple really. Use percentage for width and left properties. For example:

logo : {
  position: 'absolute',
  top : 50,
  left: '30%',
  zIndex: 1,
  width: '40%',
  height: 150,
}

Whatever width is, left equals (100% - width)/2

Carlos Cavero
  • 3,011
  • 5
  • 21
  • 41
-1

Well, I would use this way to center absolute Views

  <View style={{ position: 'absolute', left: '50%', marginLeft: -22 }}>
           <View style={{ position: 'absolute', width: 44, height: 44}}>
             <Ionicons name="close" color="#4775f2" size={32} />
           </View>
   </View>

Notice that In the View which is wrapping the Icon container I'm using left: 50% and the marginLeft is special because you need to put exactly the middle width of the child an turn it negative which in this case is 44 as you can see above, and that's it