Smart Vertical Centering Using CSS and Javascript

I’ve been up for a while now wrestling with a seemingly simple problem–how do you vertically center a fixed-size DIV without allowing it to crawl off the top of the page? And it turns out that the solution was much simpler than I expected, so I initially looked right past it. It includes some JavaScript though, so it’s not right for everyone.

Here’s the setup: I have a fixed-size div containing a flash movie. I want this flash movie to appear perfectly centered most of the time (easily done using some simple CSS), but I also want it to respect the top of the page, so if a client’s window is shrunk below the height of the movie, the top doesn’t appear “cut off”.

The first step was to do the centering. Let’s say my div, called “content_container”, is 900px by 675px. This CSS will center it both horizontally and vertically:

#content_container {
position:absolute;
width:900px;
left:50%;
top:50%;
margin:-337px 0 0 -450px;
}

Works! Unless, of course, the browser window is less than 675px high, in which case the div (while technically still centered) shifts off the top of the page. This is the issue.

My first instinct was to use Javascript to grab the coordinates of the div and make sure the top was at least zero. If it wasn’t, I’d set it to zero. And while that worked well for keeping the top from sliding off the page, it introduced a logic issue: once I set the top to zero, a test for “less than or equal to zero” is useless, and the div is stuck in one position. In other words, even if the user resizes their browser to an acceptable size, once the script fires the div will be stuck at the top.

After tinkering with it for like an hour, I realized that I’ve been taking the wrong approach. I don’t need to know the div’s position at all. All I need to know is whether or not the window is at least 675px high. If it’s not, I set the top to 337px (which, counting the negative margin, puts it at zero). If it is, I reset the top to 50%, and we have our centering back.

So first, I figure out the height of the window (adapted from this handy bit of code, which is pretty browser-friendly all the way back to IE4):

function getWinHeight() {
var myHeight = 0;
if( typeof( window.innerWidth ) == ‘number’ ) {
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
myHeight = document.body.clientHeight;
}
return (myHeight);
}

Now I check this height against our div’s height, which is 675px. If it’s less than that, I reset the top to zero. Otherwise, I make sure the top is 50%:

function fixPos() {
var thisTime = getWinHeight();
myDiv=document.getElementById(‘content_container’);
if (thisTime < 675) { myDiv.style.top = "337px"; } else { myDiv.style.top = "50%"; } }

I call this fixPos() function from both the onLoad and onResize events. And while using the onResize event can make things a bit twitchy (especially in Firefox), it totally works. Of course, folks with JavaScript turned off will have to settle for the non-corrected position.

If anybody has another, cleaner way to vertically center a fixed-size div, gimme an email. I’d be totally interested to see it.

3 thoughts on “Smart Vertical Centering Using CSS and Javascript

Leave a Reply