Have you ever wondered how does Netflix.com, Yahoo Photos or DealOgre.com popup an interactive dialog and make the main window appear dark, transparent and inactive behind it?
In this article I will show how to implement a custom modal dialog in a web browser, also known as a "smoke glass" effect. This effect makes the entire page appear behind a transparent dark shade, except for the custom dialog, simulating a modal behavior in which the user must use the dialog and not the main window. This is a very cool effect which is not using window.showModalDialog but its own solution. The solution is simpler then you think so read on.
Here is an example from Yahoo Photos, as you can see the main window is inactive and the user must complete the operation on the dialog to proceed.

So how is this effect achieved?
The trick is to cover the whole page with the "Smoke Glass", which will make it inactive, yet still visible, and at the same time show the active Dialog with some logic. My custom solution simply uses two HTML DIV elements. The first DIV is the shade element which has black color and transparency set via a CSS style, and the second is the Dialog DIV.
When the page loads, both DIVs are present but are hidden. The "shade" DIV also does not have any set size. When some action is initiated the shade DIV is set the size of the active window and shown on top of all of the elements on the window. At the same time the Dialog DIV is shown on top of the shade DIV.
Here is what my implementation looks like. Notice how all the elements appear inactive and shaded. And you can toggle the shade on and off

See a demo : SmokeGlass
Here are the CSS definitions for the DIVs
<style>
.shade{
background-color black;
position:absolute;
top: 0px;
left: 0px;
width:100%;
height:100%;
filter:alpha(opacity=25);
-moz-opacity:.25;
opacity:.25;
z-index:5;
padding: 0px;
margin: 0px;
}
.popup{
background-color:#EEEEEE;
position:absolute;
top: 200px;
left: 200px;
width:200;
height:100;
border:1px solid black;
padding:5px;
z-index:10;
text-align:center;
}
</style>
The styles for the shade and dialog can be defined in a separate css file or in the same HTML as the rest of the code. Notice that the Z-INDEX property specifies the order of the elements and since popup is set to 10 it will be on top of the shade which is 5. Also notice that the shade has black background color and 25% opacity or transparency. Both elements are absolute positioned. All of these properties are supported in both IE and Mozilla/Firefox browsers.
The JavaScript that controls the modal behavior is pretty simple and has several functions:
<script language="JavaScript" type="text/javascript">
function calcSize() {
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == ‘number’ ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in ’standards compliant mode’
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
return [myWidth, myHeight];
}
function smokeGlassON(){
document.getElementById("smokeglass").style.visibility = ‘visible’;
document.getElementById("smokeglass").style.width = calcSize()[0];
document.getElementById("smokeglass").style.height = calcSize()[1];
window.onresize=function captureResize(){
document.getElementById("smokeglass").style.width = calcSize()[0];
document.getElementById("smokeglass").style.height = calcSize()[1];
};
}
function smokeGlassOFF(){
document.getElementById("smokeglass").style.visibility = ‘hidden’;
window.onresize=null;
}
function openPopup(){
document.getElementById("dialog").style.visibility = ‘visible’;
smokeGlassON();
}
function closePopup(){
document.getElementById("dialog").style.visibility = ‘hidden’;
smokeGlassOFF();
}
</script>
The smokeGlassON activates the shade div and shows it, the smokeGlassOFF hides it. Similarly the openPopup and closePopup show and hive the Dialog div. A small amount of the logic is needed to calculate the current size of the active browser window and make the calculation cross browser compatible. This is done with the calcSize(). Also if the browser window is resized the shade div needs to be adjusted as well. This is done by assigning a handler function to the window.onresize event.
window.onresize=function captureResize(){
document.getElementById("smokeglass").style.width = calcSize()[0];
document.getElementById("smokeglass").style.height = calcSize()[1];
};
And that is really all there is to it! The Dialog in this example is absolute positioned when it appears, but it can be made drag-able with a little extra effort. Since the dialog is simple DIV, its contents can be anything imaginable, complex or simple, such as dynamic data fetched from server via AJAX, (as Netflix.com and DealOgre.com are doing), an iframe, RSS feed, etc.
Here is the rest of the HTML code on the page and also download the example file which contains all of this code.
<body>
<!–Visible HTML elements–>
<textarea rows="5">Type here if you can…</textarea><br>
<input type="button" onclick="openPopup()" value="Activate Modal Dialog">
<!–Visible Smoke Glass element which will cover the whole page –>
<div class="shade" id="smokeglass" style="visibility:hidden"></div>
<!– Sample PopUp Dialog box –>
<div class="popup" id="dialog" style="visibility:hidden">
<p><a href=# onClick="smokeGlassON()">SmokeGlass ON</a></p>
<p><a href=# onClick="smokeGlassOFF()">SmokeGlass OFF</a></p>
<p><a href=# onClick="closePopup()">Close</a></p>
</div>
</body>
Download Source
SmokeGlass.html
smokeglass.js (Open link and click File->Save)
About the Author
Vlad Kofman is working on the enterprise-scale projects for the major Wall Street firms. He has also worked on the defense contracts for the U.S. government. His main interests are object oriented programming methodologies, UI and the design patterns.







Save to Del.isio.us
Reddit!
Digg it!
Hi Vlad,thanks for this well written article. One question: Why do you define height:100%; twice within the .shade CSS class? Is this required or is it just a typo?ThanksMarkus W.
Its a typo-Vlad
Software Development Guide…
I couldn’t understand some parts of this article, but it sounds interesting…