5

I'm not able to center an inner, position: absolute element inside of an position: relative element ( https://jsfiddle.net/qL0c8cau/ ):

html,body,div {margin:0;padding:0;}
.one {
  position: relative;
  margin: 50px auto;
  width: 200px;
  height: 100px;
  background: #900;
}
.two {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  margin: auto;
  background: #0f0;
  opacity: 0.3;
  height: 160px;
  width: 400px;
}
<div class="one">
  
  <div class="two"></div>
  
</div>

I can't see what is wrong with it. I set everything correct, but it's not aligned horizontally for some reason.

What am I doing wrong here?

Samvel Aleqsanyan
  • 2,812
  • 4
  • 20
  • 28
sifa
  • 51
  • 2
  • the `margin:auto;` on the `.two` seems suspect. Why are you setting its margins if its absolutely positioned? – zgood Apr 27 '18 at 15:35
  • @zgood because this is the way to align it. Take a look how it's aligned from top and bottom. Anyway, I think I got this one. – sifa Apr 27 '18 at 15:37
  • I should point it here: it's not about negative values and transform properties. Don't suggest it please, I'm aware of them too – sifa Apr 27 '18 at 15:38

5 Answers5

4

Add this to your css

.two {
  position: absolute;
  top:50%;
  left: 50%;
  transform:translate(-50%,-50%);
  margin: auto;
  background: #0f0;
  opacity: 0.3;
  height: 160px;
  width: 400px;
}

This code will ensure that, no matter how big your containers are, the inner one will always remain in the centre of the outer one.

html,body,div {margin:0;padding:0;}
.one {
  position: relative;
  margin: 50px auto;
  width: 200px;
  height: 100px;
  background: #900;
}
.two {
  position: absolute;
  top:50%;  /* this to center the box w.r.t to parent */
  left: 50%;/* this to center the box w.r.t to parent */
  /* Above 2 lines wont fully center it, the next line internally centers it, buy moving itself 50% left and top */
  transform:translate(-50%,-50%);
  margin: auto;
  background: #0f0;
  opacity: 0.3;
  height: 160px;
  width: 400px;
}
<div class="one">
  <div class="two"></div>
</div>
Scoots
  • 3,048
  • 2
  • 21
  • 33
Gautam Naik
  • 8,990
  • 3
  • 27
  • 42
0

In div .two, instead of using left: 0; and right: 0; to place the div in the center, use transform: translateX(-25%); as an alternative. I think the reason the left and right properties don't work is because .two is inside .one, and it counters the positioning, even though .two has a position of absolute.

JSFiddle

.two {
  position: absolute;
  top: 0;
  bottom: 0;
  transform: translateX(-25%);
  margin: auto;
  background: #0f0;
  opacity: 0.3;
  height: 160px;
  width: 400px;
}
Jos van Weesel
  • 2,128
  • 2
  • 12
  • 27
0

The main issue is the inner element's (.two) width is greater than it's parent (.one). I cleaned up (change color and opacity for no confusion) and check it out:

*If you want the inner element width to be greater than it's parent on purpose, check out Guatam's answer

html,
body,
div {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.one {
  width: 400px;
  height: 200px;
  margin: 50px auto;
  position: relative;
  background: red;
}

.two {
  height: 160px;
  width: 160px;
  margin: auto;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  background: blue;
}
<div class="one">

  <div class="two"></div>

</div>
StefanBob
  • 4,857
  • 2
  • 32
  • 38
0

You using a smaller px width in the insider div

You use 400px width inside 200px width

That's why you get it like that

If you want to center a div, it should be in the size of the relative parent

    html,body,div {margin:0;padding:0;}
    .one {
      position: relative;
      margin: 50px auto;
      width: 400px;
      height: 100px;
      background: #900;
    }
    .two {
      position: absolute;
      top: 0;
      bottom: 0;
      right: 0;
      left: 0;
      margin: auto;
      background: #0f0;
      opacity: 0.3;
      height: 160px;
      width: 200px;
    }
    <div class="one">
      
      <div class="two"></div>
      
    </div>
mooga
  • 3,136
  • 4
  • 23
  • 38
0

Alternatively, you can use flex for your above problem! More convenient and modern solution for your problem.

Check browser support for flex

.wrap {
  display: flex;
  justify-content: center;
}

.one {
  display: flex;
  width: 400px;
  height: 200px;
  background: #fa0;
  justify-content: center;
  align-items: center;
}

.two {
  background: #627;
  height: 160px;
  width: 200px;
}
<div class="wrap">
  <div class="one">
    <div class="two"></div>
  </div>
</div>
Saurabh Sharma
  • 2,422
  • 4
  • 20
  • 41