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! 🙂
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".
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
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
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';
How would you put a loading image (gif, something like
http://www.ajaxload.info/cache/FF/FF/FF/00/00/00/19-1.gif) in the
middle of greyed out screen?
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)
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.
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?
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
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.
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.
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!
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.
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
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
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
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