Use jQuery to “turn off the lights” while watching videos

Some videos on YouTube have a cool feature called “Turn the lights down”. Basically, when you turn lights down, the entire page darkens and let you watch video as if you are in the cinema. This tutorial will show you how to implement this simple effect.

View live demo 

The problem

Our example is simple – it consists of header, the video, “turn off the lights” link and sidebar with some information about the video. At the code below you can se the “command” div that contains lightSwitcher link, “movie” div that contains the video and “description” div that acts as a sidebar:

    <div id="container">
        <div id="header">
            <h1>Janko At Warp Speed</h1>
            <h2>Turn off the lights - demo</h2>
            <div id="command">
                <a class="lightSwitcher" href="#">Turn off the lights</a>
            </div>
        </div>
        <div id="movie">
            <object width="560" height="340">
                <param name="movie" value="http://www.youtube.com/v/Mlahvvymkxc&hl=en&fs=1&color1=0x3a3a3a&color2=0x999999" />
                <param name="allowFullScreen" value="true" />
                <param name="allowscriptaccess" value="always" />
                <embed src="http://www.youtube.com/v/Mlahvvymkxc&hl=en&fs=1&color1=0x3a3a3a&color2=0x999999"
                    type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340">
                </embed>
            </object>
        </div>
        <div id="description">
            <p>Some description ges here</p>
        </div>
    </div>

CSS for this is simple:

body {font-family:Arial, Sans-Serif; font-size:13px; text-align:center; margin:0px; }
#container { width:960px; margin:0px auto; text-align:left; overflow:hidden;}
#movie {border:solid 1px #dcdcdc; float:left; width:560px; text-align:left; margin-right:20px;}
#description { float:left; width:320px;border:solid 1px #dcdcdc; padding: 10px 20px;}
.lightSwitcher {background-image:url(light_bulb_off.png); background-repeat:no-repeat; background-position:left;
                       padding: 0 0 0 20px; outline:none; text-decoration:none;}
.lightSwitcher:hover {text-decoration:underline;}

Let there be… dark

When link “Turn off the lights” is clicked, we need to darken the entire page. All except the movie. This can be achieved using a div that has to have the exact dimensions as the current document and semi-transparent black background. This div needs to be positioned absolutely inside its relatively positioned container (and that is BODY) and to stretch from the upper-left to the bottom-right corner.

Let’s add a div to the end of our markup:

<div id="shadow"></div>

Now let’s style it:

#shadow {background-image:url(shade1x1.png); position:absolute; left:0; top:0; width:100%; z-index:100;}

Important thing here is z-index. In order to make it cover the entire page, it has to have the largest z-index. Embedded element will be seen, anyway. It’s easy to position a div to the top-left corner and set the width to 100%. But what about the height? If we set the height of our shadow div to be 100% it will cover the entire page only if contains larger than a window, or – if we have scrollbars. Otherwise, it will cover just the content.

Let’s involve jQuery

$(document).ready(function(){
    $("#shadow").css("height", $(document).height()).hide();
});

Aaaaand…. Action!

This code set the height of shadow div to the same value as document height and hides it. Of course, we want this div visible, only when we click on “lightSwitcher”. Now we need to ad a click handler for lightSwitcher:

$(".lightSwitcher").click(function(){
    $("#shadow").toggle();
});

If you try to run this now you will see that it works. LightSwitcher will toggle shadow div visibility and that will simulate turning lights on and off. The only problem is that the link itself will be “in the dark”, and you won’ta be ble to click on it again, once you turn the lights off.

The solution is simple; LightSwitcher has to have z-index higher than shadow div. In order to do that, we have to position the link absolutely inside the relatively positioned container and set z-index to 101:

#command { position:relative; height:25px; display:block;}
.lightSwitcher {position:absolute; z-index:101; background-image:url(light_bulb_off.png);
                      background-repeat:no-repeat; background-position:left; padding: 0 0 0 20px;
                      outline:none; text-decoration:none;}

Now it will work. If you look at the demo you will notice that while you toggle the lights, link text and icon changes. In order to do that we have to extend our CSS and jQuery a little bit. When you turn off the lights, light bulb icon and text changes, and link color turn to yellow. We need to define a CSS class that will style the link and add some jQuery to change text and toggle this CSS class.

.turnedOff {color:#ffff00; background-image:url(light_bulb.png);}

We’ll extend the click handler a little bit to get this result:

$(".lightSwitcher").click(function(){
    $("#shadow").toggle();
        if ($("#shadow").is(":hidden"))
            $(this).html("Turn off the lights").removeClass("turnedOff");
        else
            $(this).html("Turn on the lights").addClass("turnedOff");
});

Now we have fully functional light switcher functionality. In the end, the complete code will look like this:

CSS

body {font-family:Arial, Sans-Serif; font-size:13px; text-align:center; margin:0px; position:relative;}
#container { width:960px; margin:0px auto; text-align:left; overflow:hidden; position:relative;}
#movie {border:solid 1px #dcdcdc; float:left; width:560px; text-align:left; margin-right:20px;}
#description { float:left; width:320px;border:solid 1px #dcdcdc; padding: 10px 20px;}
#command { position:relative; height:25px; display:block; margin: 25px 0 0 0;}
.lightSwitcher {position:absolute; z-index:101; background-image:url(light_bulb_off.png);
                      background-repeat:no-repeat; background-position:left; padding: 0 0 0 20px;
                      outline:none; text-decoration:none;}
.lightSwitcher:hover {text-decoration:underline;}
#shadow {background-image:url(shade1x1.png); position:absolute; left:0; top:0; width:100%; z-index:100;}
.turnedOff {color:#ffff00; background-image:url(light_bulb.png);}

jQuery

$(document).ready(function(){
    $("#shadow").css("height", $(document).height()).hide();
    $(".lightSwitcher").click(function(){
        $("#shadow").toggle();
        if ($("#shadow").is(":hidden"))
            $(this).html("Turn off the lights").removeClass("turnedOff");
        else
            $(this).html("Turn on the lights").addClass("turnedOff");
    });
});

Update: Thanks to @Joranovski fix for Mac would be: “position:relative; and the z-index 101 or 102 for the Movie div”.

Do you like this effect? I think it’s really funny!