How to toggle the light on your website?

April 13, 2010 at 8:34 pm 7 comments

Light switch buttonToday, 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>
<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: 1.4em;}

div {padding: 40px 20px;}

#below {background-color: orange;}

#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: yellow;
	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 the light on/off we will need a bit of javascript 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.

But first things first: the important property in use her is 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. A positioned element has its position CSS property set to either absolute, relative or fixed (as in our case).

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 (since the shadow DIV is absolutely positioned relatively to its parent which is the BODY element).

The relative position isn’t an option either 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), you can try changing the shadow DIV position CSS property to relative in the complete code file provided at the end of this post to see the result.

So … fixed. fixed provides the advantage of triggering the absolute model positioning. Thus our shadow DIV will be absolutely positioned relatively to it parent: the page (i.e. the shadow DIV is a child of the BODY element). Also the shadow DIV will be fixed relatively to the viewport. Whether you scroll up or down the shadow DIV won’t “move”. However the content underneath or above will scroll with the page as usual.

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-index CSS property allows us to control the order in which HTML elements are layered,
  • z-index only works on positioned elements,
  • by setting the shadow DIV position CSS property to fixed, we insure it is “fixed” relative to the viewport (the browser window) independently of the page current scrolling position,
  • by setting its width and height to 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 normal 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 yellow 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>
<head>
    <meta charset="UTF-8">
    <title>How to toggle the light on your website?</title>
    <style>
        body {font-size: 1.4em;}

        div {padding: 40px 20px;}

        #below {background-color: orange;}

        #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: yellow;
            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>
Advertisements

Entry filed under: Web Development. Tags: , , .

Hello world! Simple website design using CSS

7 Comments Add your own

  • 1. D  |  January 24, 2011 at 6:01 pm

    Thank you very much .. exactly what i needed.

    Reply
  • 2. Plufferne  |  February 26, 2011 at 12:35 am

    Nice site ….

    Reply
  • 3. internet marketing tools  |  March 19, 2011 at 9:11 am

    Regards for helping out, wonderful information.

    Reply
  • 4. Andy  |  August 8, 2012 at 5:38 pm

    Hi,
    I don’t know if your still active, but I’ve been using your code for a while, but now suddenly it seems to have stopped working in Chrome.
    Not sure if there was an update in chrome or something but now when you Toggle the Lights Off, it Toggles it over the Video/SWF files as well now.
    I thought it might be something to do with the z-index but can’t work out a solution yet.

    Any ideas?

    P.S IE and other browsers work fine, it’s just Chrome.

    Thanks for your time,
    Andy.

    Reply
  • 5. Andy  |  August 8, 2012 at 5:43 pm

    Hi,
    Me again.
    After writing that previous comment I worked it out…
    Finally!!!…..it was bugging me for hours!

    In case anyone else had the same situation here was the fix.

    I had to wrap the SWF Flash Code in this:

    Code/Text to Keep the Lights On Over or the Code to embed your Video/Flash File

    Thanks again for sharing your guide!

    Andy.

    Reply
    • 6. p6ril  |  August 8, 2012 at 6:06 pm

      Thanks Andy,

      I’m glad you managed to work it out and to know that my code is actually used out there 🙂
      Not sure I fully understood your solution though, your fix (if it was some sort of html code) seems to have been cut off your comment.

      Cyril

      Reply
  • 7. Andy  |  August 9, 2012 at 8:43 am

    Heya!
    Yes it is used very much hehe 🙂

    Hmm, the comment didn’t post the HTML, I’ll try again…

    I had to wrap the SWF Flash Code in this:

    <DIV STYLE=”z-index: 100; position:relative”></DIV>

    to Keep the Lights On Over or the Code to embed your Video/Flash File.

    Andy.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed


Calendar

April 2010
M T W T F S S
    Jun »
 1234
567891011
12131415161718
19202122232425
2627282930  

Most Recent Posts


%d bloggers like this: