26

How can I achieve absolute centering with CSS-in-JS? When I use the following code, my component moves across the screen. I guess the translate is being applied many times instead of just once. What's going on, and how can I fix it without using a library?

  render() {
      return (<ComponentASD 
        style={{
        position: 'absolute', left: '50%', top: '50%',
        transform: 'translate(-50%, -50%)'
      }} />);
    }
James L.
  • 12,893
  • 4
  • 49
  • 60
  • What is the `position` attribute of your component's parent? – larz Sep 11 '18 at 21:15
  • 1
    Would need to see the component and the parent component it is rendering in to help you. Not all components can map styles 1 to 1 if they are fragmented or wrapped in an non DOM element. Also absolutely positioned elements will flow to the first parent with a `relative` position. – mattdevio Sep 11 '18 at 21:18
  • The parent is `relative` positioned. It is a regular `div`. The rendered component is MUI CircularProgress - https://material-ui.com/demos/progress/. @mattdevio made a good point about it not being wrapped in a DOM element, so I wrapped the `CircularProgress` in a div and applied the absolute styling to the div, which works! – James L. Sep 11 '18 at 21:21
  • Possible duplicate of [How to center an element horizontally and vertically?](https://stackoverflow.com/questions/19461521/how-to-center-an-element-horizontally-and-vertically) – rishat Sep 11 '18 at 21:30
  • Centering a div is done in CSS, not in React. So, this question then turns into "How to center an element in CSS". [What React Does (and Doesn't Do)](https://daveceddia.com/what-react-does/?ck_subscriber_id=152812864) – Dan Cron Jan 28 '20 at 16:08

6 Answers6

53

Another option is to use flex-box.

<div style={{
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
}}>
    Hello world
</div>
asdf1234
  • 645
  • 4
  • 7
47

Your example code works well:

ReactDOM.render(
  <div
    style={{
        position: 'absolute', left: '50%', top: '50%',
        transform: 'translate(-50%, -50%)'
    }}
    >
    Hello, world!
  </div>,
  document.getElementById('root')
);

https://codepen.io/anon/pen/JaLLmX

It has to do something with your layout.

Marcel
  • 664
  • 6
  • 4
2

Thanks for the testing+comments! The styling ended up being fine, the issue was somehow caused by the layout of ComponentASD, which is actually MUI's CircularProgress https://material-ui.com/api/circular-progress/#demos

I wrapped that component in a div inside of render and applied the styling to the div, which fixed the problem (keeps it stationary and properly aligned).

James L.
  • 12,893
  • 4
  • 49
  • 60
  • 1
    Yea, I tested it in their MUI sandbox, and the affect is weird. The object moves based on the spinner progress. I would imagine that the transform affect is being overridden in the keyframe animation. Wrapping the component in a div does fix the issue. If you want to get rid of the extra div, you could use flex box on the parrent. I tested it and that works. ` display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center',` – mattdevio Sep 11 '18 at 21:33
1

This is flexbox you will need to use this on the parent Component.

   .Parent {
        display: flex,
        flexFlow: row nowrap,
        justifyContent: center,
        alignItems: center,
    {

It will center the children vertically and horizontally You can also align each component as I've shown you below

render() {
  return (<Childcomponent 
    style={{
    display: flex,
    flexFlow: row nowrap,
    justifySelf: center,
    alignSelf: center,
  }} />);
}
Justin Meskan
  • 618
  • 1
  • 9
  • 32
1

If you want to have a properly scrollable list if the window's height is smaller than the content's height you want to center, you can do this (based on this CSS answer):

<div
style={{
  display: "table",
  position: "absolute",
  height: "100%",
  width: "100%",
  top: 0,
  left: 0
}}
>
<div
style={{
  display: "table-cell",
  verticalAlign: "middle",
  textAlign: "center"
}}
>
// Here comes the content you want to center
</div>
</div>
Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
0

If you want to use it in a component just call it in the component:

.Login {
text-align: center;
background-color: #2681C6;
min-height: 100vh;}

Your jsx file sould have something like just to call it, using "className":

<div className="Login"><div>