the latest

Create a Modal Dialog Using CSS and Javascript

Back in my early programming days, before I switched over to web development, I spent most of my time writing software for Windows. I look back on that time with fond memories. 8-bit icons, OLE2, and no silly Start menus. With the recent Web 2.0 boom, many web developers have returned to their roots and begun building sites that resemble desktop applications. AJAX (the second coming of javascript) lets designers borrow elements from the desktop paradigm and use them on their websites.

One element that I find myself using quite a bit are modal dialogs. In a desktop application, a modal dialog is a box or message that forces you to dismiss it before you can use any other part of the program. When used sparingly, it can be a great way to direct the user's attention to a specific element and force them to make a decision. With a little CSS and Javascript we can accomplish this same effect on the web.

Here's a working example of what we'll be building.

The code behind this effect is surprisingly simple. There are three pieces involved:

  • A <div> containing the content you want to appear when the modal area is activated.
  • Two CSS rules which keep the layer hidden until needed and then "fullscreen" when activated.
  • Javascript which hides and shows the <div>.

The overlay <div>

At the bottom of your HTML, create a <div> with id = "overlay". Any content placed inside this area will initially be hidden by the browser and then shown modally when activated. Any content beneath it will be "unclickable" by the user, which forces them to interact with whatever message you give them.

Inside #overlay I usually place another <div> which I center horizontally and apply a few styles to create a dialog box appearance. It's this second <div> that actually contains the content I'm showing the user.

<div id="overlay">
<div>
<p>Content you want the user to see goes here.</p>
</div>
</div>

The CSS

There's only one CSS rule to take care of the fullscreen/hiding for #overlay.

#overlay {
visibility: hidden;
position: absolute;
left: 0px;
top: 0px;
width:100%;
height:100%;
text-align:center;
z-index: 1000;
}

You can style the inner <div> however you like. As I said above, I usually center it horizontally to give it more of a dialog box look and feel.

#overlay div {
width:300px;
margin: 100px auto;
background-color: #fff;
border:1px solid #000;
padding:15px;
text-align:center;
}

The Javascript

The javascript that controls everything is insanely simple. Just add the following function to wherever you're storing your javascript. (That could be in the <head> of your document or in an external .js file.)

function overlay() {
el = document.getElementById("overlay");
el.style.visibility = (el.style.visibility == "visible") ? "hidden" : "visible";
}

The javascript grabs our overlay element and then toggles its visibility property. If it's hidden, it makes it visible and vice versa. You could create a function to explicitly show or hide the layer, but I prefer this automatic toggle method since it requires less code.

With the function in place, we then call it whenever we want to show the overlay and then again to hide it. So, somewhere on our page we could add

<a href='#' onclick='overlay()'>Click here to show the overlay</a>

When the user clicks on the link our javascript will show the overlay.

Within the overlay's HTML, we need to add a link to hide it. The code is exactly the same:

Click here to [<a href='#' onclick='overlay()'>close</a>]

Finishing Touches

Combining all the pieces together we can create a simple example. (View the source to see everything put together.)

However, when the user clicks the link to show the overlay, they may become confused since it looks like they can still click on any element in the page. To help them understand what's going on, we can apply a background image to the overlay <div>. In Photoshop I create a simple checkerboard pattern .png with transparency. This creates a shaded effect so the user can still see the underlying web page but know not to click on it. To add the background to the layer, add the following to our CSS.

#overlay {
visibility: hidden;
position: absolute;
left: 0px;
top: 0px;
width:100%;
height:100%;
text-align:center;
z-index: 1000;
background-image:url(background-trans.png);
}

And finally, (as always) we need to add a small tweak so that this works in Internet Explorer. Fortunately, it's quick fix. Add this to your CSS.

body {
height:100%;
margin:0;
padding:0;
}

In order for an element to have a percentage height applied to it (which #overlay does), IE requires the parent element to have a height. So, just set body's height to 100% and zero the margins and we're all set!

Update:

Reader Henrik Binggl commented that this technique doesn't work on form elements in IE6. I did some digging and found an article on MSDN that explains the problem, which, as it turns out, only applies to <select> elements — not all form elements. In short, they are rendered as a seperate window by IE which floats above all other page content regardless of their z-index. There is a workaround, but it's complicated and messy. The Microsoft page recommends waiting as the problem has been fixed in IE7.

posted by /
Tyler Hall

posted on /
03/29/2006

comments /
40

Post a Comment

How can i set the position of the div right of the mouse cursor? Namely i want to click some buttons/images and the new dialog/form appears right there. Thanks

entertainment
06/27/08
08:54 am


Cool. Excellent help.

Afzal
06/22/08
08:00 pm


It turned out that it was the very small background image causing the problem as it was being redrawn on the x and y axis. If you replace this tiny image with a bigger one, say 100x100 in size this remove the performance hitch in IE7. Hope this helps others, thanks.

ajclifford
05/27/08
07:45 pm


Hmm, like PaW, I too am having IE7 completely lock up with 50%+ CPU usage, if you wait it will eventually load, until you click something again of course. Any ideas?

ajclifford
05/20/08
08:28 pm


This worked great for me. I hadn't played with overlay's before now and this was a great introduction. Thanks very much for your nice easy code to follow.

ajclifford
05/20/08
06:17 pm


Correction to #29 above: Resizing browser window can take almost half a *minute* in MSIE7, though I have 1GB of system RAM (and 128MB of dedicated video RAM) running only WinXP SP2 with a P1.6GHz Pentium Mobile. For some reason, loading the .png in MSIE7 is not instantaneous. Also, as for the suggestion to the transparency/opacity "cut-off" problem, setting #overlay's height to a higher value, it will create "dead space" to the end of the webpage...the transparency .png will be stretched, but along with it your webpage, creating unnecessary space -- unless you calculate the exact percentage needed to cover the particular webpage but not go over it (and thus creating that dead empty space)....

PaW
05/03/08
08:40 am


#27: I was messing around with the code and did something that caused the dialog box/modal window to flash by real quick. Sorry, don't recall what it was I had done to cause that! #26: I solved this transparency problem by setting #overlay's height to 500% (you can use whatever arbitrary value to cover the length of your page). #5: The subModal code is wonderful (and thank you for your contribution to it) but it's really complicated and I can't figure it out; nothing a relative n00b can hack, unlike this code. Moreover, subModal causes horizontal scrollbars to appear in Firefox 2! There's a solution that's been very (very) briefly mentioned in the subModal newsgroup of Google Groups but, like I said, the subModal code is way too complicated for n00b hacks like me to figure out how to customize, much less fix! =( Everybody: Do you have problems with this present sitening.com modal window code in MSIE 7, where loading time is concerned?? For some reason, IE7 takes 100% CPU capacity to load the background .png!! Resizing the browser window also takes almost half a second to render!!!

PaW
05/01/08
05:18 pm


Nice work, The demo works flawlessly... but when I implement it, the background image isn't shown? What am I doing wrong? Rory

Rory Slegtenhorst
04/29/08
06:21 am


Another weird problem. My modal dialog box appears, but only for a split second, then its goes away. Can't figure out why it just flashes up there for only a second. Any ideas? Thx

Roger
03/26/08
03:58 pm


I don't know why my post got deleted but I have discovered a workaround to a bug you are having when resizing the page small enough to where a scroll bar shows, and you scroll down, the transparency is cut off. For IE dynamically change the body overflow to hidden and then back to auto when closing the overlay. Works the same in FF except the scrollbar disappear, the overlay just sits over it. To fix that, make a div around the contents of the body with width and height 100% and change that overflow dynamically as well.

stark
03/26/08
03:21 pm


I have written something very similar to this, and I came across this looking for a fix to this bug I have and it seems you have the same issue as me. If you resize the browser window up far enough to where a scroll bar pops and you scroll down, the transparency div cuts off. It isn't too big of a deal.. Just annoying. Please let me know if you find a fix for this.

stark
03/22/08
04:13 am


broken link for demo

Livingstone
01/24/08
05:49 am


the links given in this article don't work..:((( Tried to open the sample page and even the gif but it doesn't go thr. Is this site not working nowadays....

Sachin
01/16/08
03:51 pm


FYI, for those of you have problems with your dropdown boxes showing through; put a div around all of your controls(say we call it "mainDiv". Then, in the javascript where you show the modal("overlay") div, you can use the CSS display option to hide all of those controls, including the dropdowns. ie: document.getElementByID("overlay").style.visibility = "visible"; document.getElementById("mainDiv").style.display = "none"; This works in IE6 to hide all of your controls, which makes the dialog less confusing.

Joe
12/03/07
03:30 pm


Can someone help me.. why blinking cursor is not visible on text field over a frame. This Problem is coming in firefox.. Plzzzzz suggest what to do..??

Vandana
04/10/07
02:21 am


This is simply not the way to create modal dialog boxes. This code as lots of problems in scrolling & in disabling the background content

Rizwan Liaquat
04/03/07
01:30 am


@Raju: You should probably go see Yahoo User Interface http://developer.yahoo.com/yui/ they have examples movable dialogs. You can also use http://script.aculo.us drag & drop. It should be almost 0 work to implement.

wishcow
03/18/07
09:02 am


@Pavel: Indeed there is a problem with scrolling, however, I fixed it by creating a div for the lower layer inside the body of the html (not containing the overlay div). #the-body { height: 100%; width: 100%; overflow:auto; margin:0; padding:0; } In this div you put your actual body, and leave the overlay stuff outside.

wishcow
03/18/07
08:59 am


Nice article. This works fine but I have some additional features to be added to this. I need a movable dialog. Can anyone suggest me how to make this modal dialog movable?

Raju
03/14/07
03:03 am


Couple Newbie questions... I put the #overlay{} and #overlay div {} in between style tags and this works. If I put this in a StyleSheet.css (using Visual Studio 2005) it doesn't. Also, I have not been successful getting the background-image:url(overlay.gif) to work. I have created one and put it into a project folder called Images. TIA.

Neal
02/27/07
12:23 pm


Can someone tell me how you create the overlay.gif. I've been having problems creating an opaque gif.

Petey
02/13/07
03:46 pm


Your code doesn't work with scrolling. Try to resize window until scrollbars appears. Then call your dialog and try to scroll...

Pavel Kaplin
02/09/07
10:47 am


Okay, I know this is far fetched, but I came upon the following problem in firefox 1.5: I implemented the modal dialog described above and i had it defined over a div with overflow:auto. When the dialog is not being shown, the rendering of the div below gets funked up. Each time, parts of the div are being shifted either vertically or horizontally. If you come up against this problem, a solution for this is to change the property hiding the dialog to display:none instead of visibility:hidden. Also in the function change to: el.style.display= (el.style.display == "block") ? "none" : "block";

wishcow
12/27/06
11:09 am


a workaround to disable the under-layer stuff (buttons, links, etc): put the background layer and the popup layer in two separate divs and finally include them in a third. add a background color to the background layer with opacity filter (this disables all the stuff under), add a background color to the popup (this way it will be able to be 100% opaque, since it is not nested in the background and thus will not be transparent also). finally the toggle needs to be triggered on both layers at the same time, that is why you need to put both in a third container. and here it goes in code (i use a different positioning method, so do not be fooled by that. i use this one coz it positions to the center vertically too): CSS --> .poptogg { visibility:hidden; } .popback { position:absolute; left:0px; top:0px; width:100%; height:100%; background:#000000; filter:alpha(opacity=60); opacity:.60; } .popstyle { position:absolute; left:50%; top:50%; margin-top:-100px; margin-left:-100px; width:200px; height:200px; background:#000000; } HTML -->   Wahtever text. close window JAVASCRIPT --> the same as above

oizys
12/25/06
10:36 am


[...] http://www.sitening.com/blog/2006/03/29/create-a-modal-dialog-using-css-and-javascript/ [...]


setting overflow:auto to the inner div of the overlay div solves this problem in most situations.

wishcow
12/01/06
09:10 am


The missing blinking cursor seems to be a bug in FF, if a div with CSS attribute overflow:auto exists in the background.

wishcow
12/01/06
08:23 am


Very nice, although I have a strange problem in FF1.5. If I put a form inside the modal div, I can't see the blinking cursor when I click an input control or a textarea. Have any idea why this happens?

wishcow
11/30/06
09:58 am


[...] Fast-forward to The Happy Shiny Web 2.0 days. Some enterprising individuals have figured out how to create modal windows with CSS and JavaScript. While their solution is very clever, I think modal dialogs are even more rarely needed in web applications than in traditional desktop software. I’ll explain why. [...]


[...] Create a Modal Dialog Using CSS and Javascript [...]

Blogmarks « michelc Blog
10/10/06
04:12 pm


I've taken the submodal code and enhanced it a bit here as an alternate solution: http://gabrito.com/files/subModal/

Todd Huss
04/12/06
02:15 pm


I've taken the submodal code and enhanced it a bit here as an alternate solution: http://gabrito.com/files/subModal/

Todd Huss
04/12/06
02:15 pm


You're right about being able to navigate to the other links via the keyboard, but I don't know of any easy way around this. Off the top of my head, the only solution I can think of would be some javascript that attaches an onfocus event to all links not contained inside the modal div layer. When onfocus is fired, if the div layer is visible, restore focus to the modal area. Anyone want to write this? :)

Tyler Hall
04/06/06
09:26 am


You're right about being able to navigate to the other links via the keyboard, but I don't know of any easy way around this. Off the top of my head, the only solution I can think of would be some javascript that attaches an onfocus event to all links not contained inside the modal div layer. When onfocus is fired, if the div layer is visible, restore focus to the modal area. Anyone want to write this? :)

Tyler Hall
04/06/06
09:26 am


Sorry but with keyboard navigation all link are useable

goetsu
04/06/06
01:59 am


Sorry but with keyboard navigation all link are useable

goetsu
04/06/06
01:59 am


perfect ... but: just perfect look in firefox. but a problem with ie6. i have a number of select fields. they are somewhere above the overlay (z-index)? any solution?

Henrik Binggl
04/04/06
03:01 pm


perfect ... but: just perfect look in firefox. but a problem with ie6. i have a number of select fields. they are somewhere above the overlay (z-index)? any solution?

Henrik Binggl
04/04/06
03:01 pm


Nice, thanks.

Petr Stribny
03/30/06
12:57 am


Nice, thanks.

Petr Stribny
03/30/06
12:57 am


comments


is your robot hungry? Subscribe to the feed

Categories

Archives