CSS: Relatively Centering Absolutely Positioned Elements

Yup... you you can do it so long as you're willing to do a little light math--and you can even do it in a somewhat responsive way. Here's a quick overview of the various ways to center an element with absolute positioning.

Background: CSS Centering

Centering and CSS have always been a challenge; I don't think this all that contentious a claim. If you think about it for more than a second, though, you can imagine why this might be the case: center is a relative term--it can only be defined within the context of another element. In order to center something, then, you have to establish a relationship. If you've been styling with CSS for more than a short minute, you're likely familiar with one of the ways CSS can build these relationships: namely, absolute positioning.

css is terrifying for more than a few developers

With absolute positioning, one parent element (often a <div>) is styled with position: relative;, while an element subordinate to it is styled as position: absolute;. This allows you to give the subordinate element a "fixed" position (not to be confused with position: fixed;) relative to the the parent item. Here's a quick illustration:

Parent
Child

To do this, you position the child element relative to the borders of the parent. In the above illustration, the child element is zero pixels from the top and left margins of the parent. The CSS for this would look something like this (as pertaining only to the positioning):

.parent {
  position: relative;
}

.child {
  position: absolute;
  left: 0px;
  top: 0px;
}

This is an extremely useful way to establish a relationship. It gives us the basis from which we can tackle centering the child item to the parent item.

So, how do we go about centering the child element?

Centering: The Breakdown

One way to do it would be to give the parent and child a fixed width and height. We could then do some math (i.e., subtract the child width from the parent width, divide by two) and get a number that would allow us to position the child in the center. Hopefully it's obvious why, in a world of responsive design, this probably isn't the best way to do it.

Another method might be to express the child as a percentage of the parent. You might notice that, in my illustration above, the child is exactly 1/3 the width and height of the parent. I could do similar math (subtract child width and height from the parent, and divide by two) to position the child in a more responsive manner. Here, the parent will still have a fixed height, but I'll allow the parent width to shrink. By expressing both the child and its position as a percentage of the parent, it will always remain centered--it's size being proportional to the parent. Here it is in practice:

Parent
Child

Here's what the CSS might look like:

.parent {
  position: relative;
  max-width: 800px;
  width: 100%;
  height: 300px;
}

.child {
  position: absolute;
  width: 33.33%;
  height: 33.33%;
  left: 33.33%; /* i.e., (100% - 33.33%) / 2 */
  top: 33.33%; /* ditto */
}

It's important to note, though, that this implementation also has limits. Since the child element is a percentage of the parent, as the parent shrinks, the child will quickly lose space for the content inside. That might cause some nasty wrapping. The illustration below is positioned the same as the above, but the parent has been shrunk to the point that the child content goes berserk:

Parent
The content of this child element is just too big to be styled as a percentage of the parent...

What if we want to make sure that the child element has enough space for it's content, but can still be positioned as a percentage of the parent? It can be done! We can use the calc() function of CSS. The calc() function allows us to use a mathematical equation in place of measurement unit. We can give our child a fixed width if we subtract that width from its position relative to the parent. 

Follow me for a second as we do some quick math. The dead center of the parent would be 50% from the left and 50% from the top--right? If we give our child element a fixed width and height of 100px, we could center it to the parent by subtracting half of it's width and height (50px, respectively) from 50%. The CSS would look like this:

.parent {
  position: relative;
  max-width: 800px;
  width: 100%;
  height: 300px;
}

.child {
  position: absolute;
  width: 100px;
  height: 100px;
  top: calc(50% - 50px); /* <-- CSS magic! */
  left: calc(50% - 50px);
}

This should give us a child that never experiences odd wrapping but still centers proportional to the parent; play with your window size and you should see that it resizes quite nicely:

Parent
This child won't go berserk!

The Final Word

There you have it! As the saying goes: "There's more than one way to skin a cat!". In my experience, that's often the case with CSS. Absolute positioning isn't actually my favorite way to center things (flex-box will always be my go-to). When I first encountered absolute positioning (all those years ago), it never struck me as a good way to center things. It's only more recently that I've come to see it as another valuable and power tool for coercing layouts. If you've made it this far in this post, I hope you're seeing it in a similar light!