Kimler Sidebar Menu

Kimler Adventure Pages: Journal Entries

random top 40

Improving a Lightbox Effect

Filed in:CSS
Web Dev·The Web

Improving a Lightbox Effect

August 31st, 2009  · stk

There's a spiffy-looking CSS Technique that's been getting a lot of play in the web-design and web-development social circles lately. Unfortunately, it's not a CSS technique and even as a JavaScript technique, it's crap! Did you spot it?

"Innovative CSS Technique" Making Rounds is NOT a CSS Technique

Even as a JavaScript Technique, it's Crap

This article, authored by Emanuele Feronato, has been getting some attention within the web-design and development social network recently. I've seen it Tweeted, FaceBook'd, Blogged, Digg'd and included in various "Totally Amazing CSS Techniques" lists.

On his website, Emanuele bills himself as an "Italian Geek & Programmer". Unfortunately, his article demonstrates he knows very little about web-standards, W3C validation, pure-CSS, graceful degradation, cross-browser compatibility, accessibility or white-hat SEO. He says his LightBox-like effect is "100% CSS-based" and that it's made "only with CSS - no JavaScript needed".

No JavaScript needed? What a pile of hooey!

The article is the most popular article on his blog, sporting over 252 comments and it's currently being shot across the design social circuit like it was the newest communications satellite. While some of the commentary points out the shortcomings, most (who don't know better) are lapping up this code - using it on commercial sites and passing it on.

At first blush, the technique seems very cool, but it's not code we would use and you shouldn't either. In a nutshell, out-of-the box it's crap. (Are you a web-developer, designer or programmer? Can you spot the problems?")

To learn more about why this code is crap (and to get an improved version) ... carry on ...

Closer Inspection

On the surface, A DEMO of Emanuele's code looks pretty great. To the casual observer, it appears exactly as billed: "A Lightbox Effect Only with CSS - No JavaScript Needed".

So what's wrong with it?

It's Not a CSS Technique

For starters, it's not, as Emanuele claims "100% CSS based". It's a JavaScript technique because it requires JavaScript to function. You might say, "Big deal?". It is! Emanuele claims to be a programmer, but he doesn't know the difference between JavaScript and CSS? If I was going to hire a programmer, I'd expect them to know their stuff. Would you hire someone who didn't even know the basics? No way!

It's a Crap JavaScript Technique

Emanuele's technique fails miserably if JavaScript is disabled. So, not only isn't it a 100% CSS-technique, but it's not even a very good JavaScript technique. It's not accessible. Would you hire a programmer who writes inaccessible code? I wouldn't.

The CSS Used is Invalid CSS

I'd expect my hired programmer to know about web-standards, writing clean code and use the W3C Markup and CSS validator tools.

It's not Cross-Browser Compatible

Emanuele's code breaks badly in IE6, so it's not cross-browser compatible. I'd want my programmer to write code that looked identical (or nearly identical) for every browser that my visitors used, not look good in some and not good in others.

Emanuele Lied

Look at the title. Either Emanuele (the programmer) knew what he was doing and lied about making it "only with CSS - no JavaScript needed", or he didn't. Either way, it's no good. If he knew what he was doing, then he's trying to lure people with deceit (i.e., "Black-Hat" SEO). If he didn't know, then he's not a very good programmer.

Bottom Line: I'd never hire this guy - he's either a liar or a noob - maybe both.

Eye Veh, how does this stuff like this get broadcast and lauded as being 'so great'?

I spent a couple days on this, both to set the record straight and to fix the code. The result is an improved version of this JavaScript technique (that's marketed erroneously as a CSS technique). Compare demonstrations of the original and the improved versions, below. (Note: Links open in new windows)


Here's the Shinola

Of course, you can "view source" from the above two demonstrations, to get the code and play with it yourself. Alternatively, you can also look at and play with a more vanilla version of the shiny new code, below.

The code block is a complete XHTML page, so just cut'n-paste the entire lot into a blank file. However, in doing so, you'll be missing the "non-JS.html" file. To get both, just download the ZIP file.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "">  
<html xmlns="" xml:lang="en">  
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />  
<title>Lightbox-like JavaScript Technique</title>  
<meta name="description" content=" improved version of Emanuele Feronato's Lightbox-like JavaScript Technique" />  
<meta name="keywords" content="Randsco, Emanuele Feronato, lightbox, JavaScript" />  
<style type="text/css" media="screen, projection">  
   * Copyright Sep 2009  
   * Modified from  
   * Free for personal use  
   * Commercial use requires donation  
   * see  
   * HomePage:  
    top:0; left:0;  
    width:100%;  height:100%;  
  .white_content {  
    margin-top:0em; padding:16px;  
    top:auto; left:25%;  
    width:50%; height:10em;  
    border:16px solid #ffa500;  
<!--[if IE]>  
  <style type="text/css" media="screen, projection">  
    .black_overlay {  
<!--[if lt IE 7]>  
  <style type="text/css" media="screen, projection">  
    body, html {  
      width:100%; height:100%;  
    .black_overlay {  
      width:110%; height:100%;  
  <h1 style="font-size:110%;"> - <a  href="" title=" Improving an Easy Lightbox Effect ">Easy Lightbox Effect</a></h1>  
  <p>This is the main content. To display the lightbox click <a href="noJS-lightbox.html" onclick=" document.getElementById('light').style.display='block'; document.getElementById('fade').style.display='block'; return false;">HERE</a>.</p>  
  <div id="light" class="white_content">  
    <p>This is the lightbox content.</p>  
    <p><a href="lightbox.html" onclick=" document.getElementById('light').style.display='none'; document.getElementById('fade').style.display='none'; return false;">Close</a></p>  
  <div id="fade" class="black_overlay">&nbsp;</div>  


Using the Shinola

Feel free to download and play with the improved code. As with all the code gleaned from randsco, it's free for personal use! (Note: Commercial use requires a donation).

It's a generous and straight-forward policy, which recognizes that (a) I've got nearly 3 full days invested in code modifications, article construction and testing; (b) I support the stuff I put here - answering emails, comments, instant messages, fixing, tweaking and enhancing.

All you have to do as a good netizen, is honor the policy. ;)

It's also free to learn from this article, which (hopefully) will help make your web projects more accessible, standardized, cross-browser compatible and visitor-friendly. Aspiring web developers and designers will want to carry on, as the next section goes into a bit more detail about the fixes that were employed, providing some worthwhile resources and discussion.

Making the Shinola

Making it Accessible

The biggest problem with Emanuele's original code is that it's not accessible. If visitors don't have JavaScript enabled and they click the link (to pop open the Lightbox content), what happens? Nothing ... Nada ... Zippo ... which isn't good. This will only frustrate the JavaScript-disabled visitor. They'll click the link - several times - expecting it to behave like a normal link. Ultimately, they'll leave, blaming the author and thinking that the link was bad or that the site is messed up.

Bottom line: They'll never see the content. It's not the way to get your message across, nor is creating unexpected behavior a good use of JavaScript.

Making the page accessible is simple, but it does involve a smidge more work. Just make a separate HTML page that contains the content in the JavaScript pop-up box and link to it. (This also replaces Emanuele's ugly "javascript:void(0);" link with an actual link. Imagine that!)

For static pages, like the improved code demo, just copy the entire XHTML, added a "noJS-" prefix to the new HTML file, comment out the two "display:none;" lines for both CSS selectors and make sure the link on the "close" button goes to the right location. The result duplicates the JavaScript "look" for a non-JS user. (See it here).

If you're deploying the improved code on a dynamically-served page ... LIKE THIS

This is the lightbox content.



... then you'll probably want to create a more simple "noJS" page, one that contains only the lightbox content. (See it here).


Adding an acknowledgment that the visitor has JavaScript disabled is always a good thing, as it can explain (a) what they're missing out on; (b) how they got to that page; and (c) what your site policy is regarding the usage of JavaScript, which may have the side benefit of building trust with your visitor.

Accessibility is important. In some places, it's the law, but more importantly, it's just good for business. People don't choose to be disabled, whether it's someone browsing with JavaScript disabled because their company IT department is concerned about security, or someone who was born with color-blindness. Like this technique, it often takes only a little bit of extra work to make a web page or a scripted code accessible. Good programmers, developers and designers know this. Make it part of your practice. (I'm not advocating obsessing about accessibility. Be aware of it, learn about the issues and try to follow practical accessibility guidelines).

Fixing Invalid CSS & XHTML Code

This was really the easiest part of making the improved code, as there were only a few mistakes and all were fairly simple to correct.

The W3C Mark-up Validator spat out a single error: that the <style> tag needs a "type" attribute. This tells the browser what type of data to expect and in the case of CSS, it's simply [type="text/css"]. I've also gotten in the habit of also specifying which "media" to apply these visual rules, but unlike "type", it's not required.

Some may consider it a minor point, but Emanuele's "fade" DIV doesn't contain anything - it's an empty element. Having empty elements is in your mark-up is meaningless, especially if their only function is for visual presentation. While the W3C Validator won't barf, it's not semantically correct. The fix is simple. Put something in the DIV. Anything. (I used a non-breaking space, which one can argue is just as meaningless, but technically, it's "something").

Once the XHTML errors were fixed, the W3C CSS Validator revealed three CSS errors:

  1. The property "-moz-opacity" doesn't exist
  2. "alpha(opacity=50)" can't be understood
  3. The border color "orange" wasn't recognized

Again, the fixes for these issues are straight-forward.

Drop the "-moz-opacity" property because it's (a) browser-specific (b) not defined in CSS and (c) needed only for browsers using Mozilla 1.7 or older (FireFox v0.9 and later use "opacity"). Just use opacity.

While "alpha(opacity=50)" is also browser-specific, it cannot be dropped, since it's needed by all versions of Internet Explorer in order to render opacity. However, rather than leave it in the CSS, move it into an IE conditional comment. This accomplishes two things: First, all IE-specific CSS in one location (organization); secondly, the other browsers (including the W3C CSS Validator engine) won't see it.

Web-standards include names for only 16 colors. Not all browsers recognize various color names, so it's a good habit to use HEX values for colors, rather than names. This way, you'll be assured that the browser will render your color correctly. (Change "orange" - and all the other named colors - to their corresponding HEX values).

Fixing the Vertical Scrolling Breaks

Let's talk about this first, since the fix will affect IE6.

No matter which browser you use, if you scroll using the original code, there's an ugly break involving the semi-transparent gray background (the lightbox effect). To duplicate this, head to the original code demo (using any browser except IE6). Shrink the window down so it's very short vertically (i.e., shrink the view-port till it holds only the header, content and footer). Click the link that brings up the lightbox content and scroll down. See how the shading scrolls up? Yuck.

The fix for this is easy. Just change the "display:absolute;" for the .black_overlay selector to "display:fixed;" This will effectively hold (or fix) the shaded DIV in-place, allowing the content to be scrolled underneath (at least, for most of the browsers people are using today, save one ... yep ... IE6).

Fixing IE6

Ah, IE6 ... that wonderful browser that made randsco famous and which continues to confound the world, to this day. Poor IE6. It just doesn't understand much CSS and "position:fixed;" is one of those directives that leaves it scratching its foggy head.

Ultimately, there isn't much hope for IE6. We stopped supporting it this past May and there are lots of websites that think IE6 should die. Unfortunately, IE6 is dying a slow death. As a result (and against my own better advice) I "fixed" the code for IE6, but in the end, it's an unsatisfying fix.

Here's why: Because IE6 doesn't understand "position:fixed;", one has to separately feed it "position:absolute;". But that's only for starters. In order for IE6 to understand "height:100%;" it's necessary to specify a height and width for the <html> and <body>. Even with all that extra explaining, we're back to the point where IE6 thinks 100% is only the view-port and not the entire document (i.e., we've got the vertical scroll break we had before we applied the "position:fixed;" solution for all the other browsers). Aargh!

So how do we counter that? On this dynamically-generated page (with long scroll bars), I just told IE6 that the element is much taller than it really is (i.e., "height:2000%;"). Doing so makes the scroll bars jump a tad in IE6, but for normally-sized view-ports, it makes dumb ol' IE6 look just as smart all the other - better - browsers. Unfortunately, it's still really just a red-headed country boy from upstate Washington.

This solution may be applied on a case-by-case basis. (How much over 100% you can go? I don't really know, as I've never needed to use such gigantic percentages before.) Maybe you can just use 2000% for everything?

The good news is that it's only needed for pages with scroll bars. If your page doesn't contain a lot of content "height=100%" works just fine. (Width appears to be similarly affected, but 110% took care of all the issues (for both the demo and this dynamic page). Note: These directives and their values are highlighted in red, in the above code block.)

The Shiny Conclusions

Because we're honest, knowledgeable people, we're happy to go on record and say this lightweight 'lightbox-like' effect is a JavaScript technique and not a pure-CSS technique. We've explained why having the code fail in the absence of JavaScript violates laws in certain countries and isn't good for for your website or business. We've corrected that behavior by making the code accessible. We also fixed errors in the code so that it adheres to web-standards, by using valid XHTML and CSS. We also made it cross-browser compatible and fixed the annoying visual breaks.

We've done these improvements for free and provided a detailed discussion of how we went about making these changes. We have granted anyone the right to this improved code for their personal use, again for free. We only ask for a donation if the code is used for commercial purposes, which helps to recoup the cost for fixing, writing the article and providing support and updates.

We hope that aspiring web-developers, designers and programmers learn from this article. When it comes to utilizing cool techniques and features, "Caveat Emptor" is the rule. Sometimes an Italian sports car is really a Volkswagen engine under a pretty hood. Such is the case with this original code. Learn your craft. Learn to tell the 'awfully good' from just plain 'awful'. Keep accessibility in mind, follow web-standards, write clean code, graceful degrade your JavaScript, practice white-hat SEO, use the W3C validation tools, etc. Be constantly vigilant. Test, tinker, test and test again. Ultimately, it's your reputation on the line.

Views: 16471 views
8 Comments · GuestBook
default pin-it button
Updated: 13-Feb-2011
Web View Count: 16471 viewsLast Web Update: 13-Feb-2011

Your Two Sense:

XHTML tags allowed. URLs & such will be converted to links.

Subscribe to Comments

Auto convert line breaks to <br />

1.flag Ben Comment
Please help... I have implemented this coding on my personal web site, but I cannot figure out for the life of me why this problem keeps persisting.

I have multiple thumbnails with this coding on them, each with a different image path obviously, images/mask.jpg, then images/mask_big.jpg for opening in the lightbox.... the problem is, on the 2nd, 3rd, etc thumbnails, it keeps opening the SAME image in thumb 1. I cant figure out why its duplicating the same image, while i have new image paths in place... any help would be appreciated. thanks!
2.flag Kopo Nicholas Comment

thank you very much for sharring !

I just would like to use this script as a "once per session" 's one. It means that I would like to use it on onload to display a warning but only the first time people are coming on this page.
The onload coding is simple but I don't know how to implement the "once per session" code.
I've tried like this :

function get_cookie(Name) {
var search = Name + "="
var returnvalue = ""
if (document.cookie.length > 0) {
offset = document.cookie.indexOf(search)
if (offset != -1) {
offset += search.length
end = document.cookie.indexOf(";", offset)
if (end == -1)
end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
return returnvalue;

function dropornot(){
if (get_cookie("droppedin")==""){
hs.addEventListener(window, "load", function() {
// click the element virtually:
document.getElementById('fade').style.display='block'; false;"

but it doesn't work...
As you can understand I'm a totaly newbie ! sorry, but thanks for your help
3.flag Ruach Comment
doesn't work anymore ?
4.flag stk Comment
Ruach - Both demos worked for me this morning in Chrome?

Kopo - What's the warning that you want to display? And why use so much JavaScript for it? (Why not just display an absolutely positioned box - your warning message - to everyone - no JS needed - and then have a JS "close" button?)
5.flag Kopo Nicholas Comment
Thank you for replying me.
The "warning" I would like to include in my home page is about to respect my copyright, as I will display photos and collages i've done. I'm ok if people copy them but don't want that they use them in their own site without telling these works are mine... so i find usefull to display this modal windows with the need to clic on a button call "I accept". and of course it could be nicer to display that modal window once only when people come for the first time on my galeries page.
Hope to read you soon
6.flag stk Comment
Kopo - If you want it so that it only shows once, per person (and only on their first visit), then I might suggest employing a cookie variable. Again I'd suggest not using JavaScript (client-based) and rather something server-based, like PHP or ASP. It would be possible to display (again an absolutely-positioned DIV with your warning message) to ALL visitors (and then write your cookie variable). Anytime there-after, if the cookie variable is present, you could skip this warning.

Simple example using PHP

Hope this helps.
7.flag Kopo Nicholas Comment
thank you stk ! : )
8.flag stk Comment
Kopo - You're welcome. Glad to help out.