Cover photo by Daniel McCullough.
Welcome back to alignment in CSS! Today's post is fake-sponsored by this gif:
By the way, it's pronounced "gif".
Have you ever tried to use a percent for
bottom for positioning something absolutely? You'd think that something like
top: 50% would work to vertically center an element...
Normally the top of the child is flush with with top of the parent, so bumping the "baseline" down aligns the top of the child with the middle of the parent, rather than truly centering it.
In order for something to be aligned, we want the middle of the parent and the middle of the child to be along the same axis.
So how do we get the child element's middle to where its top currently is?
If you happen to know the height of your inner element, and your element is positioned outside of the document flow (such as
position: absolute; top: 50%;) you can almost certainly use a negative margin to bump it up:
The formula for this is that you want
margin-top = -0.5 * $height. That is half the height of the inner container, with the margin being negative to push it in the "up" direction instead of what it would normally do (which is "down").
💡 Why can't I use a
Because CSS is cruel. The margin and padding properties accept various formats, but when a percent is specified, they use the width of the element. You can use this to make a responsive perfect square, which is cool, but it's pretty annoying when all you want to do is vertically center something.
If you don't know what your height is, you can use CSS transforms, particularly
translateY. This one doesn't even require any math, you just apply
transform: translateY(-50%) to the inner container.
This works just as well, and since it's a 2d transform it's pretty well supported.