34

I would like to create a css class so a div can be placed in the center of its parent. The code I am using is:

.centered {
    position: absolute;
    margin: auto;

    bottom: 0px;
    left: 0px;
    top: 0px;
    right: 0px;
}

It works if the parent is larger than the child element, or has the same size: https://jsfiddle.net/cy8dn1km/

But if the child is larger, then its center is not positioned at the center of its parent. Instead their left borders will be at the same place, and the child element will be extended only to right:

https://jsfiddle.net/797L7nce/

Something is wrong with the horizontal centering.

How is it possible to fix it using CSS only (without using CSS 2D/3D transformations), without adding new container elements?

1
  • 2
    I'm curious if there will be any clever answers to this one. Afraid you're out of luck though.
    – Mr Lister
    Commented Jul 12, 2016 at 11:43

8 Answers 8

25

Add left: 50%; transform: translate(-50%, 0);and remove right: 0px;

.centered {
    position: absolute;
    margin: auto;
    display: block;
    bottom: 0px;
    top: 0px;
    left: 50%;
    transform: translate(-50%, 0);
}

Demo

1
  • 1
    I dont like translate() that much in CSS, but for this problem it seems like the best solution, even if it is a 2D CSS transformation
    – Relisora
    Commented Jul 12, 2016 at 11:46
18

Here is a solution without using CSS 2D/3D transformations. You can use display: flex with flex-direction: column (this is important) on parent element and display: table on child element.

body,
html {
  width: 100%;
  height: 100%;
  margin: 0;
}
body {
  display: flex;
  align-items: center;
  justify-content: center;
  background: green;
}
.centered.d1 {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
.d1 {
  background: yellow;
  width: 50px;
  height: 50px;
}
.d2 {
  background: red;
  opacity: 0.7;
  width: 250px;
  height: 250px;
  display: table;
}
<div class="centered d1">
  <div class="centered d2"></div>
</div>

3
  • @Paulie_D Yea its weird :), also flex-direction: column is for chrome but on firefox it works with row. Commented Jul 12, 2016 at 12:05
  • Add the Bootstrap 4 classes .d-flex.justify-content-center to the container to center horizontally. They don't appear to work when the child is larger in both the x and y directions.
    – Chloe
    Commented Apr 19, 2017 at 3:50
  • You saved my ass. +1
    – nikk wong
    Commented Jul 24, 2017 at 12:21
5

If you know the dimentions of the elements you can use the left/top position at 50% with negative margins of half the element size.

I have updated your fiddle here: https://jsfiddle.net/797L7nce/2/

.centered {
    position: absolute;
    display: block;
    left:50%;
    top:50%;

}

.d1 {
    background: yellow;
    width: 50px;
    height: 50px;
    margin-left:-25px;
    margin-top:-25px;
}

.d2 {
    background: red;
    opacity: 0.7;
    width: 250px;
    height: 250px;
    margin-left:-125px;
    margin-top:-125px;
}
4

Ok i tried without 2D CSS :

Change absoluteto fixed and add some margin: auto;

JSfiddle here

body, html {
    width: 100%;
    height: 100%;
}

body {
    position: relative;
    background: green;
}

.centered {
    position: fixed;
    margin: auto;
    display: block;
    bottom: 0px;
    left: 0px;
    top: 0px;
    right: 0px;
}

.d1 {
    background: yellow;
    width: 50px;
    height: 50px;
}

.d2 {
    background: red;
    opacity: 0.7;
    width: 250px;
    height: 250px;
}
<div class="centered d1">
    <div class="centered d2">

    </div>
</div>

1
  • @IterAtor This is the reason why I suggested changing the position from absolute to fixed in my very first sentence.
    – Relisora
    Commented Mar 13, 2018 at 11:49
3

You're almost there. Just set the absolute positions to the same (large) negative number, to make enough room for the auto margin:

.centered {
    position: absolute;
    margin: auto;

    bottom: -9999px;
    left: -9999px;
    top: -9999px;
    right: -9999px;
}

https://jsfiddle.net/797L7nce/9/

1
  • 1
    inset: -9999px; is shorthand for setting bottom, left, top, and right all at once Commented Apr 17, 2023 at 23:55
2

Adding the below CSS to .d2 will solve the issue.

.d2 {
    background: red;
    opacity: 0.7;
    width: 250px;
    height: 250px;
    position:absolute;
    left:50%;
    margin-left:-125px;
}

You can check the demo here

1

In Bootstrap 4:

to center the child horizontally, use bootstrap-4 class:

justify-content-center

to center the child vertically, use bootstrap-4 class:

 align-items-center

but remember don't forget to use d-flex class with these it's a bootstrap-4 utility class, like so

<div class="d-flex justify-content-center align-items-center" style="height:100px;">
    <span class="bg-primary">MIDDLE</span>    
</div>

Note: make sure to add bootstrap-4 utilities if this code does not work

I know it's not the direct answer to this question but it may help someone

0

A simple technique is to use flex and set the child to have shrink 0.

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

.child {
  flex-shrink: 0;
}

Source with other examples:
https://mastery.games/post/how-to-pin-element-to-center-of-parent/

Not the answer you're looking for? Browse other questions tagged or ask your own question.