1

I have div a container with two elements inside, el and an absolute positioned element pp. el shares the same width and height as the container and their width can be dynamically changed.

pp should be centered to el and the container. I have a red marker in the middle of the pp div to mark it's center.

With a 30px width to the container and el, to center pp I used, translateX(-50%). From my understanding this should center pp to el. But actual result is not that. -50% moves the div a little further to the left. When tweaking -43% centers the red marker. But this -43% is not applicable to another el div with a different width.

How do I always center the pp container using translateX to another div of any size.

.container {
     width: 30px;
     margin: 0 auto;
}
 .el {
     width: 30px;
     height: 30px;
     background-color: pink;
     border-radius: 100%;
}
 .pp {
     position: absolute;
     max-width: 300px;
     background-color: yellow;
}
 .pp1 {
     transform: translateX(-50%);
}
 .pp2 {
     transform: translateX(-43%);
}
Not centered when translateX is -50%
<br />
<br />
<div class="container">
   <div class="el">
      elem
   </div>
   <div class="pp pp1">
      <div style="width:10px; height: 10px; margin: 0 auto; background-color: red;"></div>
      popoverasdasd asjdjasd sdfsdfsdfsdf
   </div>
</div>
<br />
<br />
<br />
<br />
Expected result comes when translateX is -43%
<br />
<br />
<div class="container">
   <div class="el">
      elem
   </div>
   <div class="pp pp2">
      <div style="width:10px; height: 10px; margin: 0 auto; background-color: red;"></div>
      popoverasdasd asjdjasd sdfsdfsdfsdf
   </div>
</div>

Fiddle: https://jsfiddle.net/v6o5z8a0/

3rdthemagical
  • 5,271
  • 18
  • 36
user3607282
  • 2,465
  • 5
  • 31
  • 61
  • 3
    You are required to post your markup here within your question, not a jsfiddle. Links go dead and will help no one in the future. [mcve] – Rob Feb 01 '18 at 12:52
  • 7
    You need `left: 50%` in addition to `translateX(-50%)`. The left style positions the left edge of the content in the exact centre, the translate rule then moves the content so the exact centre of it is where the left edge was (which should be the centre of your container). – delinear Feb 01 '18 at 12:53
  • Note: the `
    ` tag does not use or need a closing slash and never has.
    – Rob Feb 01 '18 at 13:06
  • @delinear is correct. that should be the answer. – bruno.almeida Feb 01 '18 at 14:13
  • I posted it as a comment as I expected this to get closed as an obvious dupe, e.g. see https://stackoverflow.com/questions/1776915/how-to-center-absolutely-positioned-element-in-div?rq=1 (and the reason I didn't just link to the dupe is because the top two answers on there are pretty outdated, but the solution I offered is answer number 3). – delinear Feb 01 '18 at 16:19

1 Answers1

2

So I changed the code a little to see what it was doing.

The comments are correct, you must do a left: 50% and a transform: translateX(-50%);.

The left:50% will move the left side of your inner element to the middle of the parent element. And the transform: translateX(-50%); will move the inner element back by 50% of its width. This will center the object in the parent.

Part of the problem in your example was:

  • The lack of a position: relative on the parent container.
  • Setting the parent container to 30px. For this to work well the parent should take 100% width.
  • Forgetting the left: 50% in the .el and .pp rules.

.container {
  height: 80px;
  outline: 1px dashed red;
  position: relative;
}

.el {
  background-color: pink;
  border-radius: 100%;
  height: 30px;
  left: 50%;
  outline: 1px dashed blue;
  position: absolute;
  transform: translateX(-50%);
  width: 30px;
}

.pp {
  bottom: 0;
  position: absolute;
  left: 50%;
  max-width: 300px;
  background-color: yellow;
}

.pp1 {
  transform: translateX(-50%);
}

.pp2 {
  transform: translateX(-43%);
}
Not centered when translateX is -50%
<br />
<br />
<div class="container">
   <div class="el">
      elem
   </div>
   <div class="pp pp1">
      <div style="width:10px; height: 10px; margin: 0 auto; background-color: red;"></div>
      popoverasdasd asjdjasd sdfsdfsdfsdf
   </div>
</div>
<br />
<br />
<br />
<br />
Expected result comes when translateX is -43%
<br />
<br />
<div class="container">
   <div class="el">
      elem
   </div>
   <div class="pp pp2">
      <div style="width:10px; height: 10px; margin: 0 auto; background-color: red;"></div>
      popoverasdasd asjdjasd sdfsdfsdfsdf
   </div>
</div>
Intervalia
  • 10,248
  • 2
  • 30
  • 60