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!

62 Responses

  1. Muhammad Mosa 17. May 2009 at 23:43

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

  2. Adeline 18. May 2009 at 00:38

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

  3. Thiago Cavalcanti 18. May 2009 at 01:13

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

  4. irfaan 18. May 2009 at 03:51

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

  5. Bobby 18. May 2009 at 04:11

    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?

  6. Kawsa Ali 18. May 2009 at 05:36

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

  7. Piotr "Mortif" Pabich 18. May 2009 at 08:19

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

  8. Janko 18. May 2009 at 08:26

    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! :)

  9. Marco 18. May 2009 at 08:37

    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!

  10. Tom 18. May 2009 at 10:17

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

    Nice idea though!

  11. Dan 18. May 2009 at 10:30

    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.

  12. Adam Meyer 18. May 2009 at 12:16

    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.

  13. Chang Huang 18. May 2009 at 12:22

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

  14. Janko 18. May 2009 at 12:33

    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?

  15. JTM 18. May 2009 at 12:54

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

  16. Gaya 18. May 2009 at 13:00

    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.

  17. Joranovski 18. May 2009 at 13:06

    @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

  18. Davide Espertini 18. May 2009 at 14:42

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

  19. Spencer 18. May 2009 at 14:48

    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…

  20. Janko 18. May 2009 at 14:55

    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!

  21. zarathustra 18. May 2009 at 17:04

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

  22. Mikael Carrara 18. May 2009 at 17:56

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

  23. scott 18. May 2009 at 18:08

    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

  24. TonyB 18. May 2009 at 19:33

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

  25. Linus 18. May 2009 at 19:55

    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)

  26. Janko 18. May 2009 at 21:04

    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?

  27. Joranovski 19. May 2009 at 08:39

    @Janko, your welcome!

  28. mohamadreza 19. May 2009 at 12:41

    brilliant idea

  29. TonyB 19. May 2009 at 12:53

    @Janko – Yeah that works. Nice one!

  30. Chang Huang 19. May 2009 at 13:46

    Working great now!

  31. Max Stanworth 19. May 2009 at 13:46

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

  32. zarathustra 19. May 2009 at 19:52

    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! :)

  33. Janko 19. May 2009 at 20:12

    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?

  34. Andrea Giammarchi 20. May 2009 at 10:51

    $("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

  35. Brian 23. May 2009 at 17:07

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

  36. William X. 23. May 2009 at 20:16

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

  37. hamid 4. June 2009 at 19:36

    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

  38. Ngo Vinh Hoa 13. June 2009 at 05:00

    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

  39. Chris Robinson 17. June 2009 at 07:26

    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

  40. Chris Robinson 17. June 2009 at 09:27

    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

  41. alex richards 26. June 2009 at 04:47

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

  42. marknad 26. June 2009 at 20:45

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

  43. Mišel Gošić 15. July 2009 at 15:52

    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.

  44. Janko 15. July 2009 at 15:59

    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 :)

  45. Maurício 29. July 2009 at 17:41

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

  46. Maurício 29. July 2009 at 20:20
  47. Francisco dos Santos 5. August 2009 at 02:06

    @Maurício

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

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

  48. jon 17. August 2009 at 04:03

    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.

  49. Lucifix 18. August 2009 at 18:41

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

    Best regards!

  50. Ivan Minic 27. August 2009 at 14:07

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

  51. UpperCanuck 21. September 2009 at 17:09

    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?

  52. Jason 1. October 2009 at 23:16

    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.

  53. Adriano Fornaciari 2. October 2009 at 20:07

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

  54. anonymous 21. October 2009 at 02:25

    This is really great..

  55. Maverick 17. December 2009 at 21:39

    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!

  56. Janko 17. December 2009 at 22:55

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

  57. Maverick 18. December 2009 at 13:51

    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/b

  58. Joshua Li 19. December 2009 at 07:28

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

  59. Dude 21. December 2009 at 06:41

    Hi,

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

    thanks,

  60. AceXe 13. January 2010 at 08:32

    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

  61. Jackson 10. February 2010 at 05:07

    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

  62. Jackson 10. February 2010 at 07:10

    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