Tutorial: How to produce the grey out effect using javascript and css

When i surf the net and saw all these fantastic feature where the screen went black-out when a user click certain link or button always makes me wonder how does it actually work? But i always do not have the time and knowledge to understand these things since my css knowledge has always been at the basic stage where understanding of it is just too little for me due to the working time that always occupate me. Recently, i have quit my job and went back to school which leaves me with a lot of space time. This has given me the chance to pump up my knowledge on css which i'm always weak in since the starting of my web programming. i would like to show my appreciation to the author of Hunlock who produce a great tutorial on this topic.

if you have a chance to visit Hunlock tutorial, you will see the above code that he wrote for this method to work. The technique to make the screen black-out is entirely depending on the CSS. What the above code does is to create a div tag just after the body tag which already have all the css rule appended into this particular div tag. But it is being hidden until a trigger occurs and turn the flag to true to display it out.

Originally, the background color of this particular div tag should be black entirely. However, with the introduction of alpha and opacity, it gives the background a feel of transparency. While the div is treated as a block level when its triggered and position at the top left hand side with the height and width being defined in the javascript, the whole screen will be occupant by the effect. The z-index will lift the div tag by z-axis (upwards) and anything below it will be covered by the black-out effect and whenever user tries to click anything below it, it will be disabled due to z-index and display:block.

function grayOut(vis, options, extra) {
  // Pass true to gray out screen, false to ungray
  // options are optional.  This is a JSON object with the following (optional) properties
  // opacity:0-100         // Lower number = less grayout higher = more of a blackout 
  // zindex: #             // HTML elements with a higher zindex appear on top of the gray out
  // bgcolor: (#xxxxxx)    // Standard RGB Hex color code
  // grayOut(true, {'zindex':'50', 'bgcolor':'#0000FF', 'opacity':'70'});
  // Because options is JSON opacity/zindex/bgcolor are all optional and can appear
  // in any order.  Pass only the properties you need to set.
  var options = options || {}; 
  var zindex = options.zindex || 50;
  var opacity = options.opacity || 70;
  var opaque = (opacity / 100);
  var bgcolor = options.bgcolor || '#000000';
  var dark=document.getElementById('darkenScreenObject');
  if (!dark) {
    // The dark layer doesn't exist, it's never been created.  So we'll
    // create it here and apply some basic styles.
    // If you are getting errors in IE see: http://support.microsoft.com/default.aspx/kb/927917
    var tbody = document.getElementsByTagName("body")[0];
    var tnode = document.createElement('div');           // Create the layer.
        tnode.style.position='absolute';                 // Position absolutely
        tnode.style.top='0px';                           // In the top
        tnode.style.left='0px';                          // Left corner of the page		
        tnode.style.overflow='hidden';                   // Try to avoid making scroll bars            
        tnode.style.display='none';                      // Start out Hidden
        tnode.id='darkenScreenObject';                   // Name it so we can find it later
		
	var msgnode = document.createElement('div');           // Create the box layer.
		msgnode.style.position='fixed';                 // Position fixed
        msgnode.style.display='none';                      // Start out Hidden
        msgnode.id='box';                   				// Name it so we can find it later
		// give it a size and align it to center
		msgnode.style.width = "300px";
		msgnode.style.height = "300px";
		msgnode.style.marginLeft= "-150px";      
		msgnode.style.marginTop= "-150px"; 
		msgnode.style.textAlign = 'center';
		msgnode.style.top= "50%";                           // In the top	
		msgnode.style.left="50%";                          // Left corner of the page	
	tbody.appendChild(msgnode);                            // Add it to the grey screen
    tbody.appendChild(tnode);                            // Add it to the web page
    dark=document.getElementById('darkenScreenObject');  // Get the object.
  }
  if (vis) {
    // Calculate the page width and height 
    if( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
        var pageWidth = document.body.scrollWidth+'px';
        var pageHeight = document.body.scrollHeight+'px';
    } else if( document.body.offsetWidth ) {
      var pageWidth = document.body.offsetWidth+'px';
      var pageHeight = document.body.offsetHeight+'px';
    } else {
       var pageWidth='100%';
       var pageHeight='100%';
    }   
    //set the shader to cover the entire page and make it visible.
    dark.style.opacity=opaque;                      
    dark.style.MozOpacity=opaque;                   
    dark.style.filter='alpha(opacity='+opacity+')'; 
    dark.style.zIndex=zindex;        
    dark.style.backgroundColor=bgcolor;  
    dark.style.width= pageWidth;
    dark.style.height= pageHeight;
    dark.style.display='block';  
	if(extra == 'Y')
		document.body.style.overflow =  'hidden';
		
	document.getElementById("box").style.zIndex = zindex+10;
	document.getElementById("box").style.border = "#000 solid 1px";
	document.getElementById("box").style.display = "block";
		

	document.getElementById("box").onclick = function() //attach a event handler to hide both div
	{
		dark.style.display="none";
		document.getElementById("box").style.display = "none";
		document.body.style.overflow = 'auto';
		
	}
	document.getElementById("box").style.backgroundColor="#FFF";  
	document.getElementById("box").innerHTML = "This is a box. Click me to exit effect.";
  } else {
     dark.style.display='none';
  }
}

However, user will still be able to use the scroll bar. This can be solve by adding this code

<span class="pun">document.body.style.overflow =  'hidden';
</span>

this will disable scrolling and cause the content to stay still. Depending on your need, the code produce by Hunlock can be alter accordingly.

test5 to test~

update: 27 June 2009****

I have changed the method above to include a box when the grey out appeared and a event handler attached with it so that it can be easily return back to its original form when clicked. Apologize if i did not make this update clean enough as i sort of made a quick update on it in order to answer Sanynn question below.

update: 12 July 2009*****

Update the method so that the box is align on the center, in order to align the box on the center when using position absolute, you must reset the four corner to 0 and margin to auto. Having problem aligning the box to center? Solve your problem easily with align center with CSS

update: 25 July 2009*****
If you are using jQuery, you may want to visit Simple Grey-Out Screen Effect with jQuery This article shows a complete grey out effect and how it can be done easily with just few lines of codes.

update: 24 September 2009*****
Updated the script so that the box will follow the scroll bar. The key is to position it 'fixed' and remember to placed up the DTD such as the one show below

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

If not IE won't align center. That's all! 🙂

18 thoughts on “Tutorial: How to produce the grey out effect using javascript and css

  1. Instead of adding style parameters to the created object directly, why not create the new div (or just code it into the page in the first place), give it an "id" attribute, and then describe its properties in a real CSS file? Then all the Javascript has to do is find the element and toggle it from visible to invisible (and back again), possibly by just adding or removing the class name "visible".

  2. Hi Mike,

    I agree with you on this one. It will make the entire code smaller and easier to maintain. Maybe for his tutorial purposes, throwing all the code and styling in one place makes the explanation of the overall gray out function more clearly? Nonetheless, i still think this is a good tutorial for beginners to understand how the flow works. But for improvement purposes what you have bring up is exactly what this particular code should have done.

    Cheers,
    Clay

  3. this code doesnt work, it only works if scrollbars are working,
    other than that it always takes the height of all content in the
    page and if the contents arent scrolling, it wont grey out the
    whole page

  4. oh..this is most probably caused by the display rule in CSS, just
    change it to fixed like this, instead of writing
    tnode.style.position='absolute'; change it to
    tnode.style.position='fixed';

  5. you just have to set the image z-index at a higher value than the greyed screen. This will make it visible above the greyed screen. And in order to make it center aligned, you can set the margin to 0 auto for horizontal alignment. If you are using the code above, you can try the following,

    var verticleHeight = screen.height/2;
    var myImage = document.getElementById("imageID");
    myImage.position ="absolute";
    myImage .zIndex = zIndex+1;
    myImage.margin = verticleHeight +"px auto 0px";

    Please take note that if your position are not absolute, zindex cannot be used. On the other hand, if you are using position fixed to fix the scrolling problem, the above code will have the same issue initially as the scrolling problem will reoccurs on the loading image. (the code has not been tested but it should work)

  6. Although it's not using CSS as it should, I like this script for its portability. I don't want to have to include a CSS file every time I use a grayed background.

  7. Hi!

    I'm trying to use this effect, but in IE7 it greys out even the thing I want to show, and makes it inclickable. For me the effect has a z-index of 50 and the div I want to show is 60, but I also tried with 2 and 1. In Firefox it works well, it's clickable (which is required to disable the effect) and it's not grayed out. I also tried to show the div before I turned on the effect. Any solutions?

  8. Hey Sanyynn,

    I have updated the method above so that a box can be appeared above the grey out box as many seems to be unsure the reason why the above method doesn't work well when there is a box on top of it. Since this grey out div box is within the body tag, anything that is hardcoded within the html will not bring the additional box above the grey out effect. This is because the grey out div box is at a higher level than the box we usually placed into the html by hard (since the grey out box is a DHTML approach of inserting a div into the body). By using the same approach to insert the div box will eliminate this problem(IE is weird). There are other ways of solving this problem too but I did this last minute at 4:12AM over here and tested it over firefox and IE 7, hope this solve your problem. Any issue you can always bring it up on here and i shall try my best to help.

    Cheers
    Clay

  9. Hi!

    Thank you for your fast reply, I'm so sad that I can't bring you good news (mainly because I'm stupid).

    I'm using jquery on my website, and I'm quite unsure how to use your solution on it.

    Here's my code:
    $("#profkep1").click(function(){grayOut(true);$("#profkepn1").show("slow");});
    $("#profkepn1").click(function(){grayOut(false);$("#profkepn1").hide("slow");});

    profkep1 is a thumbnail of an image
    profkepn1 is the same image in larger size.

    Sorry for wasting your time.

  10. well..this is kind of off topic but i will still help! please
    send me a email regarding your question. From the look of your
    declaration, if you use the exact same code from this post, it
    will gray out your screen and a box will appear which you click
    will return you to your original display. Your declaration code
    shown on your comment will not help you achieve this. Thus, the
    correct approach way is to modify the following stuff on the
    code,

    document.getElementById("box").style.width = "300px";
    document.getElementById("box").style.height = "100px";

    change the above to profkepn1 image size.

    msgnode.style.top= screen.height/3+'px';
    msgnode.style.left=screen.width/3+'px';

    adjust the position by doing some math regarding your width and
    height of your image verses your large image size.

    document.getElementById("box").style.background="url('path
    of your image')";

    the above background declaring is a CSS style shortcut term to
    tell the browser regarding the background of the box. That will
    help a bit, you do not have to use jQuery hide and show function
    since the method i post above already attached a event handler on
    the box (which is the large image on your case) which will hide
    and show respectively.

  11. This is very good information. I'm using your example and it works, but the first time I invoke the script on the page it hangs for about 5 seconds. After that it is immediate. Any ideas? I've exhausted all possibilities I could think.
    Thanks!

  12. hmm..that's pretty odd. Is there any other script or code in your page that may be causing the conflict? Try initialize the demo in this article and see whether it hang for 5 sec. The code above doesn't do anything other than basic click and CSS declaration. It shouldn't have caused the 5 sec delay.

  13. Clay,
    This was just great of you to post. It works in Firefox and IE7. I am thrilled!!

    But, I have a situation and a question. I have a very long webpage. When I activate your code from the bottom of my webpage, the box is placed off the current visible screen and at the top of the webpage that is not visable, unless one scrolls back up.

    How can I center the box vertically in the visable screen area for the user to immeidately see?

    Thank you for your help,
    Maggie

  14. Hi Maggie,

    I have updated the script for you. Now, the box will align center wherever you go! I have also updated this article 🙂

    Clay

  15. Thank you Clay for your recent update for vertically centering the box.

    I have another question and it is outside of the original intent of your article. However, I thought you might know the answer, so I must ask.

    My webpage uses your function, grayOut(), 3 times as 3 different called functions: function grayOut1(); function grayOut2(); function grayOut3()

    Each function is coded as you have provided, all the same, except for the name of the function and the box specifics of width and height and offsets. Makes the box of each function displayed a different size.

    Situation is that the box width and height displayed when the first function is called, is the same whenever one of the other functions is called. The box width and height does not change to the new size of the newly called function. The box always remains the same.

    Should I somehow clear this box width and height value at the end of each function? If yes, how can I do that?

    Thank you in advance,
    Maggie

  16. Maggie, i will advice you to only use this function one time. Just modify the parameter to take in the width and height for the box then divide them by half for the margin. Something like this,

    function grayOut(vis, options, extra, w, h) {
    ...
    msgnode.style.width = w;
    msgnode.style.height = h;
    msgnode.style.marginLeft= "-"+w;
    msgnode.style.marginTop= "-"+h;
    ...
    }

    this will help overwrite the method with each different call and its more efficient than duplicating codes.

    Cheers
    Clay

Comments are closed.