It can be a bloody pain.
Vertically aligning items can often be a knife being twisted in your guts.
(Though it may not be as bad as ghost spacing and the mind blowing z-index.)
If you’re going into HTML code for the first time (and you know who you are) then it can drive you nuts for hours as you rip out your hair trying to line everything up like peas in a pod.
If you’ve ever tried CSS vertical-align: center or baseline you may find it doesn’t work like you expect it to or it doesn’t work at all…
… it only works on inline or table-cell boxes according to my Dash entry.
The answer ain’t clear (hence why positioning drives most people nuts).
I can’t promise you’ll find the best answer in what follows however this is what has worked for me (and I’ve had months of in the trenches wrestling with it)…
Option 1: You Can Use Line Height
This was a lovely trick that I learned from Jessica Duarte, a fine mentor and front-end developer during my HackerYou HTML & CSS 2014 days (who happened to be the room-mate of an old Queen’s University acquaintance of mine named Francis D — what a small world eh?).
Say you’ve got a Font Awesome icon logo that you’ve built with a span.fa.fa-gears.fa-5x.
And you set the width and height to say… 2em each… (I find padding in this case to be an ugly way of “bulking” up the icon to the right shape.)
You’ll notice that the Font Awesome icon is not vertically “centred” or aligned.
If you try the logical answer of vertical-align nothing should happen (resulting in you tearing out your hear a quarter hour later).
So what do you do?
You change the line-height my friend.
And you realize it has nothing to do with positioning commands at all.
’Tis text related.
Simple yet not obvious (until you’re told by someone who’s already suffered on your behalf).
So I set the line-height to 2em (because I’m big on responsive and hate using pixels unless it’s the wrapper or someone puts a gun to my head).
I figure that since you set the width and height of the span.fa to 2em, matching the line-height helps to “fill it out” or “flesh it out” which puts everything back into a kind of vertical centred alignment.
So what’s the second option that I discovered?
Option 2: You Can Use Flexbox
This is a new CSS3 property that isn’t supported on the older browsers and likely IE 9 or earlier I think…
He ran a workshop a week or two back which I missed and will be running it again for us alumni (methinks) after the Side Project Session on April 26th from 2:30 to 4:30 pm.
Sadly that won’t help you unless you happen to be bouncing around Toronto.
Well I learned about it anyway because there was a nasty glitch with Semantic GS when I was positioning some div elements for my Simple Resume example where the 4th div block was always out of alignment.
When I saw Drew’s email I realized I might have found the current “Holy Grail” for not only “side-to-side” horizontal positioning but also vertical positioning…
… as long as you know your web site or app isn’t going to be used by many IE users anyway.
So what do you do?
Say you’ve got a nav bar for example like what I have in this theme derivative of mine…
Say you want the bottoms of the buttons or the baseline to line up — for both the right buttons and the smaller left side buttons.
We’re not talking the central axis here.
Say the parent of both of these nav menus is header#demo-header.flex-container (in the CSS/SCSS) where I use .flex-container class to hold these two rowdy “children” menus.
I apply display: flexbox to the parent so I can get these two kids “in line” — specifically baseline (where they both sit their rumps on the floor instead of jumping up to the central axis).
The CSS/CSS3 code looks something like this:
flex-flow: row wrap;
justify-content: space around;
The key property on the parent is align-items: baseline though you could use “center” if you wanted the nav menus to be “skewered” like a shish kebab.
What About Using Flexbox In The Example From Option 1?
Let’s be clear that in the situation I used in option 1, flexbox will work for you however it’s a tad tricky.
You’d have to apply display: flex on the parent (i.e. section.highlights .hl_block span.fa).
Since the actual Font Awesome icon is actually stored in the ::before element which in the DOM is a child of “section.highlights .hl_block span.fa” it will work.
The code looks something like this…
align-items: center; (this time we’re “skewering” or vertically aligning through the central axis)
If you left it at that however this is what your icon would look like inside of its containing parent…
At first you’d think this is game over: “Aw blimey, the flexbox messed up the centring of the icon inside its parent even though the icon is perfectly centred vertically and horizontally.”
Don’t worry — just centre it by applying margin: 0 auto which is the magic wand here.
The final code tally that’s spit out by Chrome Dev Tools is:
Are these the only two options?
Someone may have come up with something more clever (or more complex).
Maybe CSS4 will make vertical alignment drop dead simple.
It’s the endless march, ladies and gents.
These are the two solutions I’ve found so far.
If you’ve got a better way drop a line.
Writing from the Beaches
P.S. Do you want to get the low down on the “flexbox” Holy Grail? Check out the CSS tricks Complete Guide to Flexbox.
Above Photo Credit
“muscle power | Flickr – Photo Sharing!,” last modified June 13, 2010, https://www.flickr.com/photos/skinnyghost/4697434586/.
Technorati Tags: css3, positioning