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

May 17, 2009

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!

Let's discuss this on twitter.

62 Comments

  • Muhammad Mosa (May 17, 2009)

    Cool demo Janko, LOL, you made me laugh, really cool idea and very funny. I laught once I read the post title already

  • Adeline (May 18, 2009)

    This is something different! I like it :) an alternative to the ‘lightbox’ effect.

  • Thiago Cavalcanti (May 18, 2009)

    Well done, but I would have made it become even darker…

  • irfaan (May 18, 2009)

    doesn’t seem to work on safari 4 osx :(
    *entire* page dims.

  • Bobby (May 18, 2009)

    The flash video also gets covered when I ran the demo in Safari 3 on a mac :( Kind of ruins the effect. Perhaps placing a z-index:102 on the movie div would fix the issue?

  • Kawsa Ali (May 18, 2009)

    Very cool Concept. I Like it. As usual awesome post Janko

  • Piotr "Mortif" Pabich (May 18, 2009)

    Very cool effect but on Safari 3 OSX it makes the full page "lights out". Like someone said great alternative for lightbox :)

  • Janko (May 18, 2009)

    Muhammad: yeah, if you try to imagine someone trying to turn off the lights by clicking, sounds funny! Actually something like that happened to me several times. After hours of working I tried to move my mouse cursor over the light switch on the wall and to turn on the lights. Too much work can seriously harm your senses :)

    Adeline, Kawsa: Thanks!

    Thiago: I used the same transparency as Google, but I agree it can be a little bit darker.

    irfaan, Bobby, Piotr: Looks fine in Safari/Windows. I guess z-index:102 should resolve the problem on Mac too. Thanks! :)

  • Marco (May 18, 2009)

    Nice one Janko! Although there have been written many tutorials about this concept, this tut takes it on from a totally different angle.

    Once again, keep up the great work mate!

  • Tom (May 18, 2009)

    Same in FF3 on Mac… the dark overlay covers the whole screen including the video.

    Nice idea though!

  • Dan (May 18, 2009)

    This is cool but I’d have liked the transition to be smoother. Maybe a fade-in over 300ms or something so that it’s still near enough instant but just that little bit softer.

  • Adam Meyer (May 18, 2009)

    Cool Idea Janko.

    You can however get this same effect without using a PNG. Transparancy is supported across all browsers if you do it correctly (including IE6).

    background: black;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 100;
    opacity: 0.75;
    filter: alpha(opacity = 75);
    zoom:1;

    the zoom 1 is needed for IE. Also this will make it so the shadow stays full window size even if the user resizes it.

  • Chang Huang (May 18, 2009)

    It doesn’t seem to work on Firefox 3 OSX.

  • Janko (May 18, 2009)

    Marco: Thanks!

    Dan: Sure, why not, fade-in & fade-out would fit perfectly.

    Adam: Thanks for the tip!!

    Tom, Chang: Does z-index:102 helps?

  • JTM (May 18, 2009)

    I can confirm that it doesn’t work on Firefox 3 OSX. The whole page turns black, incl. the film… Too bad.

  • Gaya (May 18, 2009)

    Really cool Janko! I’ve always liked this feature on websites. I believe divx already had that feature in their web player. But the lights turned down automatically. very very useful! I even like it pitch black when watching.

  • Joranovski (May 18, 2009)

    @Janko, if you add a position:relative; to the div with id Movie and the z-index 101 or 102.
    it works on ff 3 on a mac

  • Davide Espertini (May 18, 2009)

    Nice and unusual (for me) tutorial Janko! I love your title, it makes me laughing when I think to it!
    Great work boy! :D

  • Spencer (May 18, 2009)

    Yeah, doesn’t work for me on Firefox 3 on a Mac. It darkens everything and won’t allow you to click play on the YouTube video. Weird…

  • Janko (May 18, 2009)

    Joranovski: Thanks for the fix !!! I updated the article :)

    JTM, Spencer: I guess it should work now.

    Gaya: Yeah, I find this trick very funny. It make me wanna watch a video even if I don’t like it :D

    Davide: Thanks!

  • zarathustra (May 18, 2009)

    Seems odd in IE8 (Win)….on your demo too…so it’s not just me! :)

  • Mikael Carrara (May 18, 2009)

    <param name=’wmode’ value=’opaque’ />

  • scott (May 18, 2009)

    I tried something similar here when you click the preview button. I’m still developing it so I’m not sure if it’s 100% yet.

    http://www.scottslab.com/acm_new/watch_now.php

  • TonyB (May 18, 2009)

    Whole page (inc video) gets covered in Firefox 3 on a Mac.

  • Linus (May 18, 2009)

    Your demo does not work for me. The video is also darkened – no matter if the video is playing before "turning down the lights" (Firefox 3.0.8 on Mac OS X 10.5.7)

  • Janko (May 18, 2009)

    zarathustra: It might be the same issue as on Mac. Is it working now?

    Mikael: does this fixes the issue on Mac?

    scott: yeah, it’s similar but more like LightBox. Good work!

    TonyB, scott: I updated the demo, does it works now?

  • Joranovski (May 19, 2009)

    @Janko, your welcome!

  • mohamadreza (May 19, 2009)

    brilliant idea

  • TonyB (May 19, 2009)

    @Janko – Yeah that works. Nice one!

  • Chang Huang (May 19, 2009)

    Working great now!

  • Max Stanworth (May 19, 2009)

    Thats awesome, makes a big difference actually watching on a darkened background and not a bright white background. great work janko

  • zarathustra (May 19, 2009)

    Sorry for the delay. No – the demo is still well and truly busted under IE 8 (XP) It tiles the background image in a kind of "gradient" from Dark to completely white form the top left to bottom right, I can’t even figure out how it’s doing it! Plus various divs change to this gradient when hovered. Very odd! Cannot possibly be used as is I’m afraid (Fine under Firefox still). Sorry to be bearer of bad news! :)

  • Janko (May 19, 2009)

    mohamadreza, Chang, Max: Thanks :)

    TonyB: Thanks for the feedback!

    zarathustra: That’s odd :( I checked it in IETester and it works fine. Can you provide some screenshot?

  • Andrea Giammarchi (May 20, 2009)

    $("embed,object").css("z-index:103"); for cover problem, position fixed !important and absolute after, padding and margin to 0 and … uhm, I would position the body after the click to avoid scroll problems ( e.g. resize, scroll a bit, click the light, you’ll be on top again with FireFox )

    nice idea though

  • Brian (May 23, 2009)

    Great idea! Any way to make it happen automatically when they play and stop the video?

  • William X. (May 23, 2009)

    Great tutorial!!
    Its a really nice effect just like the lightbox does to the pictures.
    Thanks for the codes.Good job

  • hamid (June 4, 2009)

    Hi
    tnx this is really usefull but i need your help ! I want to know how can i change this script in opposite way!
    I mean when i start my page it goes dark and when i click on the pictures lightbox effect goes away.
    tnx a lot

  • Ngo Vinh Hoa (June 13, 2009)

    But this example cannot hide the other flash in my website. Everything is in black exept the other flash object?. Can anyone help me please?.

    THanks a lot

  • Chris Robinson (June 17, 2009)

    Really nice effect, exactly what I was looking for but as "zarathustra" said its acting very strange in IE7 & 8 see the screenshot

    http://wp.contempographicdesign.com/images/lower_lights_ie8_ie7.png

    It has a weird fade then a tiling effect? Any help is much appreciated

  • Chris Robinson (June 17, 2009)

    Figured it out, had to change #shadow to:

    #shadow {
    position:fixed;
    top:0;
    right:0;
    bottom:0;
    left:0;
    height:100%;
    width:100%;
    margin:0;
    padding:0;
    background:#000;
    opacity:.75;
    filter: alpha(opacity=75);
    -moz-opacity: 0.75;
    z-index: 100;
    }

    Works perfectly across all browsers, except for the old browsersaurus IE6

  • alex richards (June 26, 2009)

    problems on the switch on & off, can’t click after you switch off on i.e 7

  • marknad (June 26, 2009)

    It so is simple and easy, sometimes it was necessary to spend a lot of time for it, thanks.

  • Mišel Gošić (July 15, 2009)

    Hi Janko,

    i am trying to modify this example to work with div which has some form fields (simply said instead of a movie I want to use a simple form), but what ever i try the div that contains the fields is in the shadow. Do you have any suggestions or maybe an exaple?

    Many Thanks,
    Mišel.

  • Janko (July 15, 2009)

    Andrea: thanks for the tips!!

    Brian: Hm, not sure if is there a way to do that.

    hamid: Start script onload, and hide it on some click event.

    hamid: try with fixes provided in comments

    Chris: I’m glad you made it. Well, it degrades gracefully (or totally) in IE6 :)

    alex: It works fine for me, can you give some more details?

    marknad: Thanks!

    Misel: Did you try with the fixes Chris and others provided? You can always send me details on emal :)

  • Maurício (July 29, 2009)

    In IE7 on Windows when the ligth is turned off the shadow covers the "turn on" link and the page becomes inaccessible. Any fix?

  • Maurício (July 29, 2009)

    Regarding my comment here is the fix:
    <a href="http://www.brenelz.com/blog/2009/02/03/squish-the-internet-explorer-z-index-bug/">http://www.brenelz.com/blog/2009/02/03/squish-the-internet-explorer-z-index-bug/</a&gt;

  • Francisco dos Santos (August 5, 2009)

    @Maurício

    Just add [i]z-index: 101;[/i] in [i]#container[/i].

    I tested with [i]IETester[/i].

  • jon (August 17, 2009)

    hello friends,
    I’d like to say a big thanx for this resource!

    I have a Q regarding an implementation of my own on a cms system… well, i couldn’t get this script to work on IE7 (FF3, Safari 4 is OK)… As a matter of fact, it never shows the "shadow" effect… when on click, the page remains ‘untouched’..

    This issue happens on a forum system (phpbb2) when there is a youtube video embeded on a post… When we’re on FF or Safari browsers, it works, making the whole page dark, except all the flash player areas (which is not so bad as we’re assuming)… But on IE, it never ‘darkens’ the page!

    Is it related somehow on the <div id="id="movie""> code, which has to be reference only once in a html page? Or there is another kind of compatibility issues?

    [ i ]: We’re using jquery 1.2.6

    Thanx in advance, hope we can solve this kind of ‘bug’!

    j.

  • Lucifix (August 18, 2009)

    Great plugin, but I was wondering if there is any change to make it work for images/photo (Gallery) too?

    Best regards!

  • Ivan Minic (August 27, 2009)

    Improves the experience significantly and yet it is so simple to accomplish.

  • UpperCanuck (September 21, 2009)

    Great tool! Nice job! Unfortunately, I need to be able to get this to work in IE6 (XP) however something strange is occurring. I added z-index: 101; to my container and it is present in .lightSwitcher as well but when I click to activate the effect, the lightbulb and text to turn off the effect disappears and is no longer clickable. Has anyone found a fix for this?

  • Jason (October 1, 2009)

    I had to come up with a way to do this on a video blog I created for my day job a while ago. The blog was already black so I used jQuery much like you did above and it turned out pretty good.

  • Adriano Fornaciari (October 2, 2009)

    Pretty Awesome. It’s just like being at home.

  • anonymous (October 21, 2009)

    This is really great..

  • Maverick (December 17, 2009)

    Hello!

    It need some refresh update,[b] it don’t work in a site with multi DIV Structure.[/b] All the page turn in black in IE, FF, Chrome, Safari.

    Thanks!

  • Janko (December 17, 2009)

    Maverick: The structure shouldn’t be the problem. Can you be more specific about your issue?

  • Maverick (December 18, 2009)

    Hi Janko!

    I finnaly find the solution, it’s not about your script, [b]it work awesomely[/b]. But, each webdesigner or developper must see this freed : (I don’t use z-index but div order )

    [quote]https://developer.mozilla.org/en/Understanding_CSS_z-index/Stacking_without_z-index[/quote]

    If people have all entire page black the structure must be clean for this script to work. Absolute / relative / normal / Order of each div is so important.

    I see your script more good than here http://userscripts.org/topics/18024

    Cheers!

    Demo : [b] http://tr.im/DmeC%5B/b%5D

  • Joshua Li (December 19, 2009)

    Thank you. I am going to use this for my next project. Bookmarked.

  • Dude (December 21, 2009)

    Hi,

    The "Turn on the lights" will not show on IE. Is there any fix for this?

    thanks,

  • AceXe (January 13, 2010)

    Hello,

    This script is awesome. I’m very glad, that in a few steps i did it on my website. But i have one question. Because the video is a little bit lower on the page, how can i with pressing the button, to keep the page position, and not sending me on the top of the page? :) Thanks a lot

  • Jackson (February 10, 2010)

    Very nice tutorial, this is exactly what I need. Just have a few questions. If i want to have this "lights off" button on every page of my site, how would I make that possible?

    Insert the first set of codes on the file that corresponds to the location where I want it to appear.
    Create a css file containing the location of the image(bulb) etc.
    create a jquery file.

    Is that correct? How do I call the css file? and the jquery file?

    Thanks in advance
    Jackson

  • Jackson (February 10, 2010)

    Update:

    I added the codes just like I said I would do earlier. For some reason, in Internet Explorer, the page will not go back to normal when clicking the "turn OFF the lights" link.

    Works great :
    Firefox
    Safari
    Opera

    Any idea why this is happening?

    Jackson