"CSS vertical align has me on the ropes!"
9 AM sharp. The rainy Monday washed Sunday away. I felt the weight of a grey week of work ahead of me as I brushed off my notes for a complicated case of CSS variables. I didn’t breathe before a bearded, bulky man with a prizefighting nose barged into the office. He was livid. And he was my co-worker. Looked like he hadn't slept since CSS3 was announced. Maybe it was his pale complexion, but I knew this guy was all sorts of late night trouble.
"What’s the hurry, pal?"
He dropped his laptop on my desk to show me a screen filled with pulsating frogs and empty lily pads.
"I've got a good one for you. I’m having problems centering my content. It's bad, really bad. I couldn’t sleep. And you know what? Everyone’s struggling with this, it can be a huge case — think class action and everything.”
The silly dope didn’t know what he was getting himself into. Centering a piece of content vertically was a huge mess littered with red tape. And it went up, way up, all the way to IE6. But I felt bad for the poor bastard. What can I say; I’m a sucker for a sob story.
"Settle down, Ricardo. Alex Santos, Esquire, Master of CSS, is at your service."
. . .
It might not have gone exactly like this. Maybe, just maybe, I've embellished the tale.
You see, my colleague Ricardo — the bulky, bearded guy — is a self-confessed CSS dummy. He once told me he was still using <center> in his markup. In terms of CSS vertical align mastery he is a dummy.
Anyway, getting your content correctly aligned, pretty and basically awesome isn't an easy chore in CSS. I've seen enough people struggling with it, and I keep spotting some "critical" errors in the wild, when it comes to true responsive design.
Let's Talk About the CSS Vertical Align Property
When I started working in front-end development, I had a little trouble with this property. I thought it should be used like the classic “text-align” property. Oh, if only it were that simple...
The CSS vertical align property works smoothly with tables, but not with divs or any other elements. When you use it in a div, it aligns the element alongside the other divs and not the content — which is what we usually want). This only works with
Here’s an example:
See the Pen 1#Example_OutSystems Experts - Vertical-align on divs by Alexandre Santos (@alexandre_santos) on CodePen.
We Want to Center the Content, Not the Div Itself!
You have two approaches. If you only have some div elements with text — like a navbar — you can use the
line-height property — which means you need to know the height of the element, but you don’t need to set the height. This way your text will always be centered.
This approach has a catch, though. If your text has more than one line, the line height will be multiplied by the number of lines you have. This will probably leave you with an ugly page on your hands, and no one wants that.
Have a look at this example:
See the Pen 2#Example_OutSystems Experts - Navbar with line-height by Alexandre Santos (@alexandre_santos) on CodePen.
If the content you want to center has more than one line, the best approach is to use div tables. You could use real tables, but that’s not semantically correct. Also, if you need breaks for responsive purposes, you’re better off using div elements.
For this to work, you need to have a parent container with the
display: table; property, and inside that container you will have the number of columns you want to have centered, with the
display: table-cell; (and
vertical-align: middle;) property.
Let’s look at an example:
See the Pen 3#Example_OutSystems Experts - Table cell vertical-align by Alexandre Santos (@alexandre_santos) on CodePen.
Why does this work with the table layout and not with div elements? Because when you have a table, the rows have the same height. So, when the content in the cell doesn’t use all the available height space, the browser automatically adds a vertical padding to center your content.
The Position Property
Let’s start with the basics:
position: static;— this is the default value. The element is rendered following the order of the HTML.
position: absolute;— used to define the exact position the element needs to be in. This position is always related to the closest ancestor in a relative position (not static). Do you know what happens if you don’t define the exact position of the element? You lose control over it! It is rendered randomly, completely disregarding the document flow. By default it’s displayed in the upper left corner.
position: relative;— used to position the element relative to its normal position (static). This position keeps the flow order of the document.
position: fixed;— used to position the element relative to the browser window, so it is always visible in the viewport.
Note: Some properties like
z-index only work if the element has a position (not static).
Let’s Get Our Dirty Hands Dirtier!
Do you want to align a box with the center of your page?
First get an element with a relative position and the dimensions you want. For example: 100% width and height.
The second step may be different depending on your target browsers, but you can use one of two choices:
- Old school option: You need to know the exact size of your box to remove half of the width and half of the height of the box. Like this:
See the Pen 4#Example_OutSystems Experts - Position absolute with sized box by Alexandre Santos (@alexandre_santos) on CodePen.
- Cool new CSS3 option: Add a transform property with a translate value of -50% and it will always be centered. Like this:
See the Pen 5#Example_OutSystems Experts - Position absolute without sized box by Alexandre Santos (@alexandre_santos) on CodePen.
Basically, if you want to center content, never (ever, ever, ever!) use
top: 40% or
left: 300px. This works perfectly on your test screens, but it’s not centered. Not really.
Remember the fixed position? You can do the exact same thing you did with the absolute position, but you don’t need the relative position in the parent — it will always be relative to the browser window.
CSS Vertical Align Criers: Have You Heard About Flexbox?
You can use the flexbox layout, an option that my boy Dinis wrote about some time ago. Oh yeah, it’s far better than any of the other available options. With flexbox, manipulating elements in different ways is child’s play. Even Ricardo could do it.
The problem is that you need to let go of some browsers, like IE9 and below. Let it go. Let it go... can’t hold it back anymore. (Yeah, now it’s stuck inside your head. You’re welcome.)
Here is an example of how to vertically center a box:
See the Pen 6#Example_OutSystems Experts - Flexbox layout without sized box by Alexandre Santos (@alexandre_santos) on CodePen.
Using the flexbox layout, you can have more than one centered box and have it correctly aligned. But that’s a story for another time!
And What About CSS Grid?
CSS Grid Layout is the most powerful layout system available in CSS. The main difference from Flexbox, it’s the fact that it works in a two-dimensional system, meaning it can handle both columns and rows, unlike Flexbox which is largely a one-dimensional system. For this reason, this might be appropriate for creating more complex layouts, like the Gallery pattern on OutSystems UI.
That being said, it can perfectly be used just to center elements in a container! Here is an example of how to vertically center a box:
Similar to Flexbox, this approach also needs you to let go of older browsers, although the support is perfectly stable across the major ones.
No More CSS Vertical Align Tears
Vertical alignment can be pretty much like Johnson’s Baby Shampoo: tear free. If you follow what you learned with these few examples, you can master vertical alignment in no time, too.
. . .
I passed by Ricardo's place some time later and he wasn't there. Someone told me he had fallen asleep on one of our company's many comfy couches.
Looks like a TKO.
When I looked at his laptop's screen, though...
What the hell was he doing? Playing games while he was supposed to be working?
That’s a whole lotta color for a Monday that started out so grey.
References and Further Reading