How to toggle the light on your website?
April 13, 2010 at 8:34 pm 4 comments
Today I’d like to show you a way to switch the light off on your website.
What’s the point? Simple … Imagine you’d like to display photos, or a video, or if a box should pop up (for authentication purposes for instance), it’s better if your visitors focus on what you’re trying to draw their attention to. We will help them concentrate by darkening everything else in the background.
In order to do just that we will mainly use some CSS and a bit of javascript to toogle the light on/off.
Basically here is the HTML (5) code we’ll start with:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>How to toggle the light on your website?</title> </head> <body> <div id="below">This DIV will be darkened when the light is switched off.</div> <div id="shadow"></div> <div id="above" onclick="toggle();"> <p>Click me to toggle the light on/off!</p> <p>This DIV will always be visible even when the light is switched off.</p> </div> </body> </html>
And now the CSS, I’ll explain it all below:
body {font-size: 140%;}
div {padding: 2em 1em;}
#below {background-color: yellow;}
#shadow {
display: none;
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: black;
opacity: 0.6;
filter: alpha(opacity=60);
z-index: 99;
}
#above {
position: relative;
background-color: red;
z-index: 100;
cursor: pointer;
}
As you may have guessed already it all happens thanks to the shadow DIV. Initially it is not shown: its display property is set to none in the CSS. Thus in order to actually switch off the light we will need a bit of javascript as well to change it’s display value. You may have noticed in the HTML an onclick event handler defined for the above DIV that triggers a toggle() function. We will come back to it later.
First things first: the important thing here is we use z-index.
In CSS everything is stacked. If you place a DIV inside of another DIV it’s as if the inner DIV is displayed above (on top of) the outer DIV actually masking it (provided the inner DIV background-color isn’t transparent which is the default or its opacity isn’t set to 0 for instance).
z-index values are usually managed automatically without the end-user even knowing about them. However they can also be set programmatically so that authors can control the order in which elements are displayed (or layered if you prefer). In order to darken (almost) everything we force the shadow DIV z-index property to a high value (99), so it is rendered above the elements with a lower z-index default value.
The trick is that z-index only works with positioned elements.
But we could have set the shadow DIV position CSS property to absolute so what’s the point of using fixed? Well if we had used absolute, only the viewport would have been darkened but not the entire page … let me explain this a bit further.
Imagine you look at a long web page that you need to scroll down to read entirely. The viewport is the subset of the page (i.e. the visible part) that is shown on screen in the browser window at any given time. If we had used absolute, only the viewport at the moment we display the shadow DIV would have been darkened. In other words when scrolling up or down, the rest of the page wouldn’t appear darkened.
In our case with the shadow DIV display property set to absolute the result would even be slightly different: only the top viewport would be darkened because we’ve set the shadow DIV top and left values both to 0 and they refer to the top left of the page.
Also the relative position isn’t an option because then the shadow DIV would still be part of the normal rendering flow. In other words the top and left values would be relative to the shadow DIV normal position in the flow but not to the page or the viewport as we want it. Since we’ve set some padding on all DIV elements (i.e. the shadow DIV box paddings should be rendered when displayed, see paragraph below), try changing the shadow DIV position CSS property to relative to see the result.
Now why do we define the width and height of the shadow DIV? Looking at the HTML code we see that it is empty. By default an empty DIV is rendered without any margin, border or padding and with a size of 0 (i.e. an empty DIV without margin, border or padding actually doesn’t show). By setting the width and height to 100% we ensure it covers the viewport entirely (i.e. everything that is displayed in the browser window). Moreover in case the browser window is resized it insures the viewport is still properly covered when the page content is reflowed to adjust the new dimensions.
Let’s sum up the concepts above before going any further:
- the
z-indexCSS property allows us to control the order in which HTML elements are layered, z-indexonly works on positioned elements,- by setting the
shadowDIVpositionCSS property tofixed, we insure it is “fixed” relative to the viewport (the browser window) independently of the page current scrolling position, - by setting its
widthandheightto 100% we make sure the viewport is entirely covered.
Don’t give up we’re almost there.
In this example I’ve chosen a black background color. The point is to “switch off” the light on the page but of course you could use any other color. Using white instead would give more the impression that everything is “diluted” in the background.
The opacity property allows to set a transparency effect. The background is still visible (shines through) though covered (darkened) by the shadow DIV which acts like a curtain in front of it. The opacity is set in 2 different ways. The first one (opacity: 0.6;) is the way it is defined in the CSS3 Color Module specification of the W3C. The second one is specific to IE and thus non standard. IE isn’t fully compliant with the W3C standards so this trick is required for cross browsers development. In this example I’ve set the transparency to 60% but it’s up to you to play with the value, knowing that 0 means fully transparent and 100% fully opaque.
Lets now focus for a moment on the above DIV. It’s z-index value (100) is superior to the one of the shadow DIV (99) so it will be displayed above it. In other words, it will still be visible even when the light is switched off. Remember that the z-index only applies to positioned elements wich is why its position is set to relative. relative insures the box is still part of the rendering flow, but allows us to manually set the z-index.
All we miss now is the javascript piece of code:
function toggle () {
var shadow = document.getElementById("shadow");
if (shadow.style.display != "block")
shadow.style.display = "block";
else
shadow.style.display = "none";
}
I hope this part is self explanatory. We simply toggle the value of the shadow DIV display CSS property to either none or block. Note what we could have used the visibility property instead of display, then we would have toggled the values between visible and hidden.
Conclusion
I hope you’ve enjoyed this post. There are other ways to achieve a similar result like for instance using the rgba property in CSS3 for the background color (which defines both the rgb color plus the alpha transparency at once) instead of opacity. It has the advantage that unlike the opacity it does not propagate to the children elements. However CSS3 isn’t at all supported by any IE browsers yet (apart for IE 9 beta) while Firefox, Chrome, Safari and Opera know how to deal with it (at least in their recent versions). What would probably miss from this tutorial is a bit more javascript or jQuery magic to smoothen the effect (for a simple fade animation in javascript, I highly recommend this great tutorial from Switch On the Code though obviously using jQuery would be way easier at the cost of a 30kb library download). I may write about this topic later on in another post.
In order to perform your own tests you can copy and paste the full code below into a text file, save it as whatever-name-you-like.html, open the file in any (not too old) browser and click several times on the above DIV (the one with a red background color) to see the light toggle effect.
Alternatively you can download the file directly from here. In this version I’ve added some dummy text so you can better understand the CSS position and viewport concepts and see for yourself the effect of the various position values (fixed, absolute and relative) on the page rendering. I encourage you to play a bit with the CSS and learn by experience.
What about you, do you use this kind of effect? Do you know a better way to achieve the same result? I’d be glad to hear from you in the comments.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>How to toggle the light on your website?</title>
<style>
body {font-size: 140%;}
div {padding: 2em 1em;}
#below {background-color: yellow;}
#shadow {
display: none;
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: black;
opacity: 0.6;
filter: alpha(opacity=60);
z-index: 99;
}
#above {
position: relative;
background-color: red;
z-index: 100;
cursor: pointer;
}
</style>
</head>
<body>
<div id="below">This DIV will be darkened when the light is switched off.</div>
<div id="shadow"></div>
<div id="above" onclick="toggle();">
<p>Click me to toggle the light on/off!</p>
<p>This DIV will always be visible even when the light is switched off.</p>
</div>
<script>
function toggle () {
var shadow = document.getElementById("shadow");
if (shadow.style.display != "block")
shadow.style.display = "block";
else
shadow.style.display = "none";
}
</script>
</body>
</html>
Entry filed under: WebDev. Tags: CSS, Design, javascript.
1.
D | January 24, 2011 at 6:01 pm
Thank you very much .. exactly what i needed.
2.
Plufferne | February 26, 2011 at 12:35 am
Nice site ….
3.
Tracie Kalamaras | February 27, 2011 at 9:07 pm
hopefully this comment doesn’t appear multiple times (it appears to freeze once i try to post my comment.. not certain if it’s really posting), but all I truly wanted to say was great post and thanks for sharing.
4.
internet marketing tools | March 19, 2011 at 9:11 am
Regards for helping out, wonderful information.