Why an element with absolute position and propertied left: 50% inside a div with relative position do not spontaneously make the element centered?

Viewed 25

I have a page layout with some text-element inside a div, as shown below:

body {
  background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url(../public/images/lake.jpg) no-repeat center center fixed;
  background-size: cover;
  font-family: 'inherit';
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

p,
q,
button {
  position: absolute;
  margin: 0 auto;
  left: 50%;
  /* transform: translateX(-50%); */
  text-align: center;
}

q {
  width: 90%;
  top: 75px;
}

p {
  width: 90%;
  top: 150px;
}
<div>
  <q>Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus vitae facere dolor cupiditate placeat quas.</q>
  <p>
    Lorem, ipsum dolor.
  </p>
  <button>New Quote</button>
</div>

And it renders this: enter image description here


I know the transform: translateX(-50%); will solve this problem and make the p, q, and button elements centered.

  1. But my question is why doesn't the left: 50% property solve the case spontaneously, is it because the point of reference of top/bottom/left/right property is not a top left of the div?
    1. If yes, is there any way to modify the point of reference? how?
    2. If no, what is the reason?
  2. Is there any suggestion or source of study for best practice for centering a non-100% width element inside a div element?
2 Answers

Left will place the left side of the element at 50% of it's parent.

To center the element use a negative margin-left, with half of the width:

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

p,
q,
button {
  border: 1px solid red;
  position: absolute;
  margin: 0 auto;
  left: 50%;
  /* transform: translateX(-50%); */
  text-align: center;
}

q {
  width: 90%;
  margin-left: -45%; /* added this line */
  top: 75px;
}

p {
  width: 90%;
  margin-left: -45%; /* added this line */
  top: 150px;
}
<div>
  <q>
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus vitae facere dolor cupiditate placeat quas.
  </q>
  <p>
    Lorem, ipsum dolor.
  </p>
  <button>
    New Quote
  </button>
</div>

Left 50% sets the left side of the content box at 50% of the parent's width.

If you want to center, you would need to set the center of the content box at 50% of the parent's width. But we cannot do that (not directly at least) in CSS.

You cannot modify the point of reference. You can however use Maths to change it accordingly.

If you take that 50% width, and substract half of the content's width, it would indeed make the center the point of reference.

In your example, you have a p of 90% width so: 50% - 90%/2 would give left:5%

If you need to play with pixels (200 in the following example), you'd use calc. left:calc(50% - 200px/2);

There's also a trick with using the content's margin. If you set a negative margin-left of half the width of the element, you'd produce the same result as substracting the left value.

As for your source of study and best practice... Just use google. There are tons and tons of articles on the subject of vertically centering elements. The current best practice would be with flex. This would look like this:

#mainContainer {
    display: flex; /* establish flex container */
    flex-direction: column; /* make main-axis vertical */
    justify-content: center; /* align items vertically */
    align-items: center; /* align items horizontally */
}
Related