Inspired by Lightbox: Anatomy of a Modal Window
April 11th, 2007
Ugh... that just might be the worst title I've ever written...
For a "ultra-top secret"™ web application I've been working on, I need to take all focus away from the browser screen, and allow/force the user to interact with a window before being able to continue. Commonly, these are called modal windows, and gained some credibility for having practical uses with Lokesh Dhakar's wonderful Lightbox script (incidently, I use a variation of it on this script on DerekAllard.com).
There are many variations of modal windows running around, but I wanted a simple, unanimated "overlay" would would require a user's interaction, so I set about to build my own. The first thing I needed, was an alpha transparent div to sit on top of the whole screen. I stole was inspired by Matthew Pennel's great article on Easy Cross Browser Transparency, and began building from there. The ultimate alpha transparent solution I chose was a pure CSS base.
Here's a working version of the final result. I started by adding a div named "overlay" at the top of my document.
#overlay {
background: #333;
opacity: 0.6;
filter: alpha(opacity=60);
}

"opacity" covers off most modern browsers, and the filter covers IE. If you're already feeling the rage at IE building, then maybe you should stop reading, because it just gets worse. In order to make it sit on to of the content and stretch full screen, I postioned it absolutely, and set its width and height 100%. At this point, you'll also want to make sure your body has no padding or margin, or it pushes the overlay away from the edge of the screen.
#overlay {
background: #333;
opacity: 0.6;
filter: alpha(opacity=60);
position: absolute;
width: 100%;
height: 100%;
}

Terrific. Since the overlay sits on top of the page, it disallows any user interaction. Now to get an informational box on top of the overlay. I needed another div for that.
<div id="overlay"></div>
<div id="info_box"><blockquote><p>Got any Skittle Brau? Never mind, just give me some Duff and a pack of Skittles.</p></blockquote></div>
And throw in a bit of styling.
#info_box {
background: #FFF;
border: 1px solid #333;
width: 300px;
height: 100px;
position: absolute;
}

At this point the informational chewy nugget is at the top, left (0px, 0px) of the screen. I'd like it to be centered in the viewport. Figuring out the viewport in different browsers takes a bit of work. I discussed this a little bit in my Conditionally Sticky Sidebar post, but this requires a bit more work. Without getting into details, what you really want is this inner width, cross browser javascript, respectfully borrowed from Quirksmode.
var x,y;
if (self.innerHeight) // all except Explorer
{
x = self.innerWidth;
y = self.innerHeight;
}
else if (document.documentElement && document.documentElement.clientHeight)
// Explorer 6 Strict Mode
{
x = document.documentElement.clientWidth;
y = document.documentElement.clientHeight;
}
else if (document.body) // other Explorers
{
x = document.body.clientWidth;
y = document.body.clientHeight;
}
You can now attain the viewable dimensions of the browser, and use that to position the box accordingly.
document.getElementById('info_box').style.left = (x-300)/2 + 'px'; // viewport minus width, divide by 2
document.getElementById('info_box').style.top = (y-100)/2 + 'px'; // viewport minus height, divide by 2

Great, let's admire what we've done. It works nicely in Firefox, Safari, Opera and IE 7. I'm sure it'll work nicely in IE 6 right?
Sigh...

After much searching around and experimenting, it seems the solution is surprisingly simple.
html, body {
height:100%;
width: 100%;
}
At this point, you've got a reasonably useful baseline for a modal window. The next step is in turning them on and off. The easiest way to do that is to toggle the display of our 2 divs. This is surprisingly more tricky then it first seems, and will form the basis of another entry, on another day.
And one more time before we go, the finished demo.
This entry was made on April 11th, 2007 @ 23:03 and filed into Browsers, How-To, Javascript.

Matthew Pennell wrote on April 12th, 2007 @ 4:59
The first thing I thought when after that snippet of CSS was “you’re going to need to set 100% height on the html and body elements” - you need me on IM! ;)