RailsConf 2008

The Lightbox Effect without Lightbox

Feb 09, 2006 144 comments

Particle Tree posted an article the other day on how to modify the Lightbox javascript to work with regular divs and not just images. A few days before that article went up, I had the same bit of inspiration for Wayfaring.

We’re not afraid of pushing the envelope on the site, so if we like an idea, we’ll roll with it until too many of our users tell us it sucks. (That hasn’t ever happened incidentally)

Wayfaring Login

When I first started trying to figure out how to do this, I wasted a lot of time trying to hack the Lightbox code and it was ugly. I thought better of using code I wasn’t proud of, so here’s how I did it:


#overlay{ 
    background-image: url(/images/overlay.png);
    position: absolute;
    top: 0px;
    left: 0px;
    z-index: 90;
    width: 100%;
    height: 100%;
}

* html #overlay{
    background-color: #333;
    background-color: transparent;
    background-image: url(blank.gif);
    filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(
        src="/images/overlay.png", sizingMethod="scale");
}

#box{
    width:300px;
    background:#2d2d2d;
    padding:10px;
    border:2px solid #eee;
}

#close{
    position:absolute;
    top:-5px;
    right:-5px;
    cursor:pointer;
}

Most the css was lifted straight from the Lightbox css. Next is the HTML, which also includes Lightbox’s neat little close image.


<div id="overlay" onclick="hideBox()" style="display:none"></div>

<div id="box" style="display:none">
    <img id="close" src="/images/close.gif" onclick="hideBox()" alt="Close" 
         title="Close this window" />
    Here's a bunch of really sweet content!
</div>

And finally we have the javascript. The center function was lifted directly from here with a few slight modifications. Note: You also need Prototype for this script to work.


function showBox(){
    $('overlay').show();
    center('box');
    return false;
}

function hideBox(){
    $('box').hide();
    $('overlay').hide();
    return false;
}

function center(element){
    try{
        element = $(element);
    }catch(e){
        return;
    }

    var my_width  = 0;
    var my_height = 0;

    if ( typeof( window.innerWidth ) == 'number' ){
        my_width  = window.innerWidth;
        my_height = window.innerHeight;
    }else if ( document.documentElement &amp;&amp; 
             ( document.documentElement.clientWidth ||
               document.documentElement.clientHeight ) ){
        my_width  = document.documentElement.clientWidth;
        my_height = document.documentElement.clientHeight;
    }
    else if ( document.body &amp;&amp; 
            ( document.body.clientWidth || document.body.clientHeight ) ){
        my_width  = document.body.clientWidth;
        my_height = document.body.clientHeight;
    }

    element.style.position = 'absolute';
    element.style.zIndex   = 99;

    var scrollY = 0;

    if ( document.documentElement &amp;&amp; document.documentElement.scrollTop ){
        scrollY = document.documentElement.scrollTop;
    }else if ( document.body &amp;&amp; document.body.scrollTop ){
        scrollY = document.body.scrollTop;
    }else if ( window.pageYOffset ){
        scrollY = window.pageYOffset;
    }else if ( window.scrollY ){
        scrollY = window.scrollY;
    }

    var elementDimensions = Element.getDimensions(element);

    var setX = ( my_width  - elementDimensions.width  ) / 2;
    var setY = ( my_height - elementDimensions.height ) / 2 + scrollY;

    setX = ( setX &lt; 0 ) ? 0 : setX;
    setY = ( setY &lt; 0 ) ? 0 : setY;

    element.style.left = setX + "px";
    element.style.top  = setY + "px";

    element.style.display  = 'block';
}

That’s all there is to it! To make all of this goodness appear, you just need to call showBox().

The center function is a bit long, but most of that is just browser compatibility code. If you can make it any easier than this, I’m all ears, but I’m fairly satisifed with this solution.


144 comments


Tristan Dunn said about 5 hours later:

I just tried it out and there is a noticeable delay from when the box appears to when the overlay appears. You might want to preload the overlay image or switch to an opacity only solution.

Also, why is the overlay image 101×101? Sure, being 1×1 isn’t that big of a difference, but it would help with the load speed and save bandwidth over a long period of time.

Sean S said about 6 hours later:

Yes.

I knew there was an easier [lightweight] way—I’d actually attempted a similar result last summer with my personal blog and realized it was probably too much work to be worth it.

Thanks for doing the work. ;)

Reuben Whitehouse said about 8 hours later:

Very nice indeed.

Srinivasan R said about 10 hours later:

Nice one. Gotta try that one.

Srinivasan R said about 10 hours later:

Sorry for multiple comments. As Gerald mentioned, the comment form didnt clear in FF 1.5.0.1

Scott Walter said about 12 hours later:

Awesome. I thought the lightbox code was a little too heavy.

PJ Hyett said about 14 hours later:

Adding the rel=”lightbox” would have added more complexity and code to the solution. Don’t get me wrong, that is particularly useful when you want the effect working with multiple images on the page, but it’s a bit overkill for my purposes.

As far as why the form isn’t clearing the fields after you click submit, that’s a good question. I’ll see if I can fix that this morning.

John Zeratsky said about 15 hours later:

This is a killer effect. ManiacalRage.net uses it when he puts image links in posts, like on this post: http://maniacalrage.net/past/tags/japan/

Beautiful.

Chris said about 18 hours later:

Does anyone now why I would be getting the javascript error “Element.show is not a function”?

PJ Hyett said about 18 hours later:

My fault Chris. Element.show is a Prototype function. To remove that dependency, you just need to use the normal DOM method of making the div visible.

Chris said about 19 hours later:

Thanks,

It works just great after I added the latest version (1.4) of Prototype

PJ Hyett said about 19 hours later:

Glad to hear it. I think I also have the comment issues sorted out.

Bruno said 2 days later:

Great script, PJ. I played around with it and made some improvements (at least, they’re improvements for me).

Check out my version of Lightbox.js

It abstracts your functions into a Lightbox object, and allows for some customizations. Also lets you place more than one on a page. Hope it’s useful!

Jarkko Laine said 3 days later:

Way cool, PJ and Chris!

Tristan: The size of the image file actually doesn’t depend much on the physical size when the image consists only of one color. Actually using one pixel background images is often discouraged because many browsers go nuts when repeating an image over a million times.

Alex Bosworth said 7 days later:

There is some trickiness if you have a long scrolling content no? height:100% wouldn’t cover the entire page.

PJ Hyett said 8 days later:

The CSS height attribute will only return the visible screen height, so 100% works just fine on long scrolling content.

goeko said about 1 month later:

cool

Zed said 3 months later:

Good Work!! When i got the example??

Jason said 3 months later:

this is excatly what I need but I cannot get it to work, gives me errors

lr said 4 months later:

PJ Hyatt said: “Element.show is a Prototype function. To remove that dependency, you just need to use the normal DOM method of making the div visible.”

Does anyone here speaken ze English? What’s that mean exactly? :)

(Have the latest prototype and Firebug shows the same error Chris rec’d.)

sergey said 4 months later:

download link would be nice….

lr said 4 months later:

The ‘download’ is in the code box up there. ;)

sefas said 5 months later:

asdf

drukwerk said 5 months later:

I think it’s a great way to slim down the code. Thanks!

jimy said 5 months later:

nice script, tnx u i m going to try it for my blog (:

BillyG said 5 months later:

154 errors this page, I’m thinking I’ll skip this one.

M said 11 months later:

Replace ’&’ in the following code with ‘&’ and < with ‘<’ and the code should work.

M said 11 months later:

That was supposed to be ‘&_amp;’ and ‘&_lt;’ (delete underscores.)

Jack said about 1 year later:

That looks cool

MIKI said about 1 year later:

qq 75678886

andrea said about 1 year later:

really nice. tnx a lot

Albert said about 1 year later:

Hi have you seen this: http://orangoo.com/labs/GreyBox/ you may find it does what you are looking for Al :)

gjghjg said about 1 year later:

ghj

Редирект said about 1 year later:

thanks fot it ;)

SkySoftLab said about 1 year later:

Привет!!!

Paradox said about 1 year later:

Instead of using a gif for the background, you can use css’s built in opacity property, opacity.

Neotropic Solutions said about 1 year later:

Awesome, been working on trying to get a nice over lay. Once I was using was fine in all browsers except FireFox, weird scrolling ‘stuff’ and I do use the prototype,love that file! One thing I noticed about the demo, the box. it is appearign underneath the overlay. Maybe intentional, but assumed is was a dialog to appear over the overlay while the overlay was over the page. CSS is missing a couple attributes.

position: absolute; z-index: 91;

box{

position: absolute; z-index: 91; width:300px; background:#2d2d2d; padding:10px; border:2px solid #eee; }

I also agree with below a 1×1 pixel file works better.

Neotropic Solutions said about 1 year later: Better work

/****************************************\
* Show Overlay and box
\****************************************/
function showBox(){
    $('overlay').show();
    overlayReload();
    center('box', '300', '100');// Size of the box
    return false;
}
/****************************************\
* Adjust overlay to new window size
\****************************************/
function overlayReload()
{
    if (window.innerHeight && window.scrollMaxY || window.innerWidth && window.scrollMaxX) {    
        yScroll = window.innerHeight + window.scrollMaxY;
        xScroll = window.innerWidth + window.scrollMaxX;
        var deff = document.documentElement;
        var wff = (deff&&deff.clientWidth) || document.body.clientWidth || window.innerWidth || self.innerWidth;
        var hff = (deff&&deff.clientHeight) || document.body.clientHeight || window.innerHeight || self.innerHeight;
        xScroll -= (window.innerWidth - wff);
        yScroll -= (window.innerHeight - hff);
    } else if (document.body.scrollHeight > document.body.offsetHeight || document.body.scrollWidth > document.body.offsetWidth){ // all but Explorer Mac
        yScroll = document.body.scrollHeight;
        xScroll = document.body.scrollWidth;
    } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
        yScroll = document.body.offsetHeight;
        xScroll = document.body.offsetWidth;
      }

    $('page_overlay').style.height = yScroll;
    $('page_overlay').style.width = xScroll;
}
/****************************************\
* Actually center box
\****************************************/
function center(window_name, _width, _height) {
    var successWin = $(window_name);
    var pagesize = getPageSize();    
    var arrayPageScroll = getPageScrollTop();
    successWin.style.left = (arrayPageScroll[0] + (pagesize[0] - _width)/2);
    successWin.style.top = (arrayPageScroll[1] + (pagesize[1] - _height)/3);
}
/****************************************\
*
\****************************************/
function getPageSize(){
    var de = document.documentElement;
    var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
    var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight
    arrayPageSize = new Array(w,h) 
    return arrayPageSize;
}
/****************************************\
*
\****************************************/
function getPageScrollTop(){
    var yScrolltop;
    var xScrollleft;
    if (self.pageYOffset || self.pageXOffset) {
        yScrolltop = self.pageYOffset;
        xScrollleft = self.pageXOffset;
    } else if (document.documentElement && document.documentElement.scrollTop || document.documentElement.scrollLeft ){     // Explorer 6 Strict
        yScrolltop = document.documentElement.scrollTop;
        xScrollleft = document.documentElement.scrollLeft;
    } else if (document.body) {// all other Explorers
        yScrolltop = document.body.scrollTop;
        xScrollleft = document.body.scrollLeft;
    }
    arrayPageScroll = new Array(xScrollleft,yScrolltop) 
    return arrayPageScroll;
}

Neotropic Solutions said about 1 year later: You can also do without using an PNG.

#page_overlay {
    position: absolute;
    z-index:80;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    background-color:#000;
    filter:alpha(opacity=40);
    -moz-opacity: 0.4;
    opacity: 0.4;
}

z10d said about 1 year later:

Hey, dudes, can anyone post a zip with a working demo? All this copy-pasting business is error prone and am loosing hair!

Giselle said about 1 year later:

I have to agree with z10d. It’s easier to avoid problems with a ZIP file. I can’t get it to work on my server and I’m going insane trying to figure out why.

Renato said about 1 year later:

This not work !!!! dont lost u time !!!

David Madden said about 1 year later:

I have posted a zip of a working example here.

Renato said about 1 year later:

David Madden tnks dude, now it works !!! hehe

a.p.palaniraja said about 1 year later:

it doesnt work for me with IE6 :(

Alex said about 1 year later:

a.p.palaniraja – you must make some changes (look up)

r.burke said about 1 year later:

This was exactly what I was looking for. Thanks for documenting it and posting it PJ.

Ruel said about 1 year later:

Hi. I can’t seem to display the overlay in IE6.

Zotag said about 1 year later:

A Sweet search engine, soon to have this feature.

creativemix said about 1 year later:

Is there already a fix for the overlay problem in IE6? Coz the overlay color doesn’t show in IE6.

iDanny said about 1 year later:

Ok, what files do i need? i cant find a download button…..

andyk said about 1 year later:

Thanks for this – awesome and easily modified to support multiple windows on the same page (although not at the same time obviously).

I also added onclick=”hideBox()” to the overlay window so that you can click anywhere outside of the window to close it (just like lightbox!). PS – to the guy that posted the Zip file – thanks, you made my life loads easier!

Joe said about 1 year later:

Finally this commentbox is fixed! The height part still doesnt work. Even if you look at PJ’s site that uses it, if you scroll down you see that anything below your original window height is not covered by the overlay. See here: http://www.wayfaring.com/

xzzx said about 1 year later:

xzxz

exinrex said about 1 year later:

Hello,

I just need some help. How do i put validation of the form? Pls help

Thank’s

5 said about 1 year later:

555555555

deneme said about 1 year later:

deneme

Fred said about 1 year later:

Why don’t you just make a live example on this page? I personally can’t be bothered to download something and load it up in a browser just to see a little visual effect on a web page. Do a demo!

alukar said about 1 year later:

It didnt work with IE6

nathan said about 1 year later:

nice on mozilla firefox but got errors on IE, when is going to be a solid version??

dean said about 1 year later:

Great work to all, thanks for the updates.

dean said about 1 year later:

Great work to all, thanks for the updates.

dean said about 1 year later:

Great work to all, thanks for the updates.

fsd said about 1 year later:

sdfsdfsdfsdfsdfsdfsdf

fsd said about 1 year later:

sdfsdfsdfsdfsdfsdfsdf

aaaaaaaaaaa said about 1 year later:

aaaaaaaaaaaaa

aaaaaaaaaaa said about 1 year later:

aaaaaaaaaaaaa

aaaaaaaaaaa said about 1 year later:

aaaaaaaaaaaaa

sas said about 1 year later:

asas

sas said about 1 year later:

asas

nbbvn said about 1 year later:

nvbnvbn

mmmk said about 1 year later:

HOW TO USE IT WITH WORDPRESS!!!? PLEASE HELP.

ag said about 1 year later:

niice

gjh said about 1 year later:

ghj

Coder said about 1 year later:

Excellent code. Easily implemented. Congrats and thanks for sharing :)

gelinlik said about 1 year later:

very nice article. thank you.

gelinlik said about 1 year later:

very nice article. thank you.

google reklam said about 1 year later:

thank you!

web tasarım said about 1 year later:

excellent. thank you very much!

matbaa said about 1 year later:

it’s good!

ad said about 1 year later:

asd

Boris said about 1 year later:

Very very nice. Work very fine for my login/subscrite (of course I use the zip…). Continue your nice Web ajaxification.

dafd said about 1 year later:

sfasddf

Canta said about 1 year later:

superrr.

Travis said about 1 year later:

i was going to use this method, but i found moodalbox which uses the mootools library instead of the prototype.

ganesh said over 2 years later:

Great Work! I was looking for this!

Milos said over 2 years later:

Good job! Like this one very much! Thanks for sharing!

ewr said over 2 years later:

werwer

islami sohbet said over 2 years later:

Great Work! I was looking for this!

1231 said over 2 years later:

ไรฟ่ะ

trixia said over 2 years later:

hi, ive tried the lightbox effect in one of my project (as stated) i encountered lsight problems when it loads the lightbox effect, in IE it works fine but in Mozilla, there’s a little bit delay when the lightbox try to cover the parent page with flash animations and in safari its more complicated since the lightbox pop up doesn’t cover the whole page (specially the flash animations…) is there anyway you could help me out figuring the problem? the url is www.aklan.gov.ph… it also has a problem loading css formatting within the lightbox panel

coupon said over 2 years later:

This code rockssss

tuzla nakliyat said over 2 years later:

thanks.

google reklam said over 2 years later:

thank you.

web tasarım said over 2 years later:

thanks.

lazer epilasyon said over 2 years later:

very nice article. thank you.

gebze nakliyat said over 2 years later:

thanks!

vitamin eksikliği said over 2 years later:

thanks.

sanayi arsası said over 2 years later:

very nice.

arama motoru optimizasyonu said over 2 years later:

very nice article

sağlıklı beslenme said over 2 years later:

thank you

arsa said over 2 years later:

thanks.

internet reklam said over 2 years later:

thank you

kocaeli nakliyat said over 2 years later:

thanks.

doğruların zamanı said over 2 years later:

PASSAPAROLA Yarışma Programı Başvuru Formu Başvuru Sitesi Doğruların Zamanı Yarışma Programı Başvuru Formu Varmısın Yokmusun Yarışma Programı Başvuru Formu Kim 1 Milyon İster Yarışma Programı Başvuru Formu Show tv Yarışma Programları yayın akışı canlı tv Acun Ilıcalı Reha Muhtar

web tasarımı said over 2 years later:

thanks..

AddressMan said over 2 years later:

ajax is great! thanks :)

ml said over 2 years later:

lm

cam filmi said over 2 years later:

very nice styles

personel kartı said over 2 years later:

good article

ctraos said over 2 years later:

exelente articulo muchas gracias!!

renk tshirt said over 2 years later:

tshirt imalat

tshirt said over 2 years later:

tshirt

Forma said over 2 years later:

Forma imalat Forma imalat

web tasarım said over 2 years later:

Thanks.. good

sapka said over 2 years later:

sapka şapka imalat sapka şapka imalat

çiçek said over 2 years later:

http://www.gelecegimiz.com/

çiçek said over 2 years later:

http://www.ciceknet.net/

google reklam said over 2 years later:

thnk you friend

google reklam said over 2 years later:

thnk you friend

adsl başvuru said over 2 years later:

thnx

sesli chat said over 2 years later:

tnx

nakliyat said over 2 years later:

tnx

çiçekçi said over 2 years later:

thnks

burç uyumları said over 2 years later:

veryy cool thnks

google reklam said over 2 years later:

tnx

haber said over 2 years later:

special thnx

site ekle said over 2 years later:

thnk you

reklam said over 2 years later:

where lightbox js?

evden eve nakliyat said over 2 years later:

thanks! lightbox

defibrilatör said over 2 years later:

Hey, I love it.

Thank you.

Tercüme said over 2 years later:

Wowww!! it’s very important CSS technolgy.Thank you so much for sharing this article!

Thank you!!

Nichol said over 2 years later:

Sorry, but can you make this in examples & put on in archive to download? I’ll be very greatful

çiçek said over 2 years later:

çiçekçi

çiçek said over 2 years later:

cicek

wicket said over 2 years later:

thanks

web tasarim said over 2 years later:

tasarımlarınız elimizden gecer

Ant59 said over 2 years later:

It won’t work for me. The error says “showBox is undefined”, but it finds errors within the script too, so I it must have found the file. Can anyone help?

cicek said over 2 years later:

cicek

çiçek said over 2 years later:

çiçek cicek online cicekci

Josh Walsh said over 2 years later:

You need to run the Center routing on the overlay as well, otherwise the overlay only shows properly when you are scrolled at the top of the page.

Name
Url