Even with all the 'warm fuzzies' that designers and developers alike get by keeping our markup separate from design, conforming to web standards, and getting cross-browser compatible CSS driven layouts out the door, there are still some days when we want to curse the CSS gods and go back to the comfort and predictability of tables. And of course it's always raining on those days. Just like yesterday. Even so, I found two viable solutions to the vertical alignment problem that has been plaguing us CSS geeks from the beginning.
True, CSS2 has the vertical-align attribute but it doesn't always work the way one would expect. The vertical align attribute is only applied to inline elements, such as images, or table-cell elements not block level elements (learn more about block vs. inline). So what if you wanted to vertically align a block level element, such as a div?
After some perusing of the CSS community, I found a few different solutions to this problem, however most solutions called for the knowledge of the height of the outer container and inner container which you are trying to align. But in real world development, how often do we know how tall our content is going to be? Or how tall the outer container is, especially if this outer container is the browser window? It seems these solutions do not allow for much flexibility. So I set out to try and figure out a way to vertically align a container within the browser. After some trial and error with CSS alone, I decided it was time to bring in the power of the Document Object Model (DOM) in order to find a suitable solution. Using DOM, we can find the height of our containers even if they are dynamic. For instance, to get the html body height and the height of the container I want to align I would do the following:
Once I have these values, I can use some basic math (I suppose I can't say I never use what I learned in high school anymore) to add the appropriate amount of top-padding to vertically align my element. Note, I only vertically align the container if it is smaller than the browser. Otherwise I simply use a default top padding.
Finally, I simply call the JS function that holds this code on window load and resize. This works beautifully except for one problem, the alignment does not occur until the window has finished reloading or resizing which can lead to some jumpiness of transition. Due to this awkward transition, I again decided to try and find a CSS/HTML only solution.
Thanks to this example of vertically centering at jakpsatweb, I was able to get it working via css. As mentioned previously, vertical-align not only applies to inline elements, but any element whose display is set to "table-cell". By forcing my block elements to use this display, I can now successfully use the vertical-align attribute. The html I used looks like:
Then I set up my css. I want the body height to fill the browser, so I set html, body{min-height:100%;}. I set up my siteTable div to have a display:table and min-height of 100%, and finally I set my siteTableCell div to display:table-cell; margin: 0 auto; (to horizontally center); vertical-align:middle. This will vertically align any items inside the siteTable. Lastly, I add hacks for IE just as with the jakpsatweb example. My final CSS looks like this:
And viola. Now we have a site vertically aligned to the browser window.
See live example at: http://www.d-p.com/templates/verticalAlignFinal.html

Comments (6)