I recently came across a solution on CSSPlay for a JavaScript free lightbox that uses invalid markup. So, being a sucker for a challenge, I set myself the task of creating one with valid markup and I eventually succeeded.

Here’s one I made earlier. It works in FF, Safari, Chrome, IE6, IE7 and IE8 and this article will explain how…Note: This article assumes you have a basic understanding of (X)HTML and CSS.

You will notice the markup is very simple at the moment and that we have two links leading nowhere. These links will eventually
trigger lightboxes, but before they do, we need to add the markup for said lightboxes after the container <div>:

This is by no means semantic but I chose this markup because it made managing the CSS a little simpler. I’d recommend leaving the markup as is for the purposes of following this tutorial, however, feel free to code this part as you wish as long as you use the same amount of elements and tweak the CSS where necessary.

Step 2: Making it Look Pretty

Add the following CSS to the <head> of your document (we will be doing CSS inline to simplify this tutorial):

The <li>s in my example are acting as the lightbox overlay that you see underneath the lightbox ‘box’ itself so I have given it an extremely large height of 9999px with the assumption that no one will have a resolution larger than that. The reason for not using a 100% height is because it causes a window resize bug… feel free to try it at the end of the tutorial to see what I mean and if you can come up with a better solution, please do share!

Next you will notice that I am using an RGBa background colour. If you are not sure what this is/does please read about RGBa on CSSTricks. Internet Explorer, as ever, doesn’t support RGBa so in order to get around this, we need to add some IE specific styling and markup. Place the following CSS in the <head> of your document:

Then add the following markup to the bottom of your lightboxes (before the closing </li> of each lightbox):

<!--[if IE]>
<div class="ie-bg"></div>
<![endif]-->

I’m sure someone will point out that this causes the ActiveX popup to appear in IE resulting in the non-JavaScript element of this tutorial being void however, this would still all work fine without the filter so that is purely aesthetics and not functionality.

Moving on…

Step 3: Positioning the Lightboxes

When previewing our progress you will have seen that the lightboxes currently sit below the content which isn’t much like lightbox behaviour. The lightboxes need to sit on top of our content so a few more CSS properties are required to achieve this. Append this next snippet to your #container styling:

position: absolute;
top: 0;
left: 0;

Now this is where things get a little confusing. Why did I add it to the #container and not the #lightboxes element? That’s because if I added it to the #lightboxes element it’s child elements would always be on top of our #container (no matter what) so we would never be able to click the links in the content again, even when the lightboxes are ‘closed’. Doing it this way enables us to position the #container between the #lightboxes child elements and you will see why this is necessary in the next step.

We also only ever want to see one lightbox at a time so adding overflow: hidden; to your #lightboxes styling will accomplish that. This works because the #lightboxes element was given a height of 100% in the CSS which will make it 100% height of your window. Therefore, it hides anything past the height of the window. However, Internet Explorer requires a little extra in order to achieve the same effect so make sure you add the following to your IE specific CSS within the conditional comment we added earlier:

#lightboxes {
position: relative;}

Step 4: Opening and Closing the Lightboxes

So we’ve got it looking good and everything is positioned in the right place but how do we open and close the lightboxes? Simples.

I’m sure you are all aware of linking to an an element on the same page with the use of the ID attribute and how it works. However, you may not have known that linking to an element that is hidden off the page causes the element to be “pulled” into view as opposed to the window jumping down to that element. I used the same technique on my Auto-Scrolling Slideshow Tutorial which further demonstrates how powerful this technique can be.

So with that in mind I can change the href values of our content links to the ID values of the lightboxes and create a new #close element that our close buttons will link to. Your markup would then look as follows:

You won’t be able to test this at the moment because the empty #close element is sitting on top of the #container disabling you from clicking anything. However, if you append ‘#lightbox-about’ to your URL you will notice the about lightbox appears and that changing it to ‘#close’ will bring the empty lightbox element back into view. Neat huh?

Now we need to remove the background colour from the #close element so that it looks as if nothing is there and position it behind the #container element so that we can click the #container links.

Remember I mentioned positioning the #container between the lightbox elements in the last step? Well this is why and it would not be possible if we had absolutely positioned the #lightboxes instead of the #container.

This next piece of CSS needs to be added to style the #close element as mentioned above:

#lightboxes #close {
background-color: transparent;
z-index: -1;}

Now you can open and close the lightboxes as expected!

How does that work? Well, if you do not set a z-index on an element then it will be layered depending on it’s position in the code. Therefore, the lightbox <li>s automatically appear above the container as they are further in the markup. However, by giving one of them a minus z-index I am forcing it behind any elements that precede it.

Step 5: Adding More Content to the Container

At the moment we haven’t got much content in our container so it all appears to be working fine. However, if you add pages and pages of content you will notice that we’re not quite finished. A scrollbar appears enabling you to scroll past the lightbox and it’s overlay. This is because the document is scrolling but the lightbox is only 100% height of the window, not the document. The #container is also 100% height of the window so a simple solution is to overflow the container so that it scrolls instead of the document by adding overflow: auto; to the #container element.

It will make more sense if you preview it in Internet Explorer where you will see two scroll bars. One for the #container and a disabled scrollbar for the document. This is easy to fix by adding the following CSS to your IE specific CSS:

Conclusion

This was just a bit of fun and is unlikely to be used in any real-world applications but hopefully it’s been an interesting read and you never know, someone might have actually learnt something from it!

So what now? Well, it would be great to see if anyone can come up with a better solution! If you have one, please share.

96 Responses to “How to Create a Valid Non-Javascript Lightbox”

I’m planning to use a good portion of this in a real-world website :p I dislike JS and how IE likes to disable it, and this is an awesome solution. I took out the 100% width and the background color overlay because I’m using it as a pop up window type thing 😀

To further my previous comment, has anyone else come across the mouse wheel scroll problem in IE?

It seems you can only scroll if the pointer is over the content, for example try hovering the pointer over a blank part of the page (i.e. not over text, links etc) and you’ll find that the scroll wheel doesn’t work.

I’ve found this in IE 6 & 8, so I presume would be the case in other versions of IE.

This is the last fix I need to overcome before implementing this on my site, so any help would be greatly received.

My web design instructor put it to us to find a css solution to make a gallery. Seeing as I had absolutely no idea what I was (or am) doing, and the instructor wanted something that would actually validate, your solution proved quite elegant for me. I tweaked things here and there (the photos and captions in the lightbox were cutting off on smaller screens, but I kind of fumbled my way into a solution for that.

The only thing that didn’t validate in the CSS was the rgba value … so I pretended I didn’t see it and moved on.

I have asked people to look at my site and it appears to be working on Firefox and Safari, but not on Internet Explorer (does anything work on IE?). Apparently, the links aren’t working. I know you put in a fix for Explorer, so I’m thinking I probably blew it somewhere.

Anyway, thanks … the rest of the class gave up and did javascript galleries. I didn’t … which makes me better than them. Or more stupid than them. I just don’t know enough about web design yet to know which.

Thanks verymuch this will help me a lot thanks 🙂 just to let you know it doesn’t scroll either and you have to press the X (close) to exit it you can’t click on the outside like you usually can on some websites.Thanks

I think this is fantastic — BUT you said that you don’t think it would be used in a real-world project…why is that? What is the downside…seems like being able to get lightboxes which are convenient for users WITHOUT relying on javascript, which can be a hassle, would be perfect….

unexpected results in Firefox using the mouse’s scroll wheel. Whilst the browsers scroll bars will scroll the faded background content, the scroll wheel moves the overlay and black filter down the page :S

can someone tell me how to make textarea or text box hidden so as 2 use image on it…the way it is in this blog below “Have Your Say” form…if someone could give me some css links regarding it would be very grateful….tx

The keyboard navigation in the example page is very broken. Try tabbing through the page, for example. Also the focus management is non-existent, thus creating some serious accessibility barriers of perceivability, operability and understandability.

As is fairly evident, the ‘selling point’ of not using JavaScript is counterproductive here. It produces a much worse / broken solution with no way of repairing the damage — apart from using JavaScript.

“This was just a bit of fun and is unlikely to be used in any real-world applications but hopefully it’s been an interesting read and you never know, someone might have actually learnt something from it!”

The above quote was taken from the Conclusion of this article… It was just an experimental bit of fun, it was not created to solve the accessibility issues of lightboxes or to replace lightboxes.

I certainly wouldn’t use this solution for any of my projects as there are many issues with it, including those that you’ve mentioned =)

What a brilliant concept. The amount of Javascript-driven lightboxes on the net today is endless and tons of them are absolutely beautiful. To do it completely without JS though is inventive and well-executed. You now have portable lightbox that works regardless of whether or not the end user has Javascript enabled or not.

I love this. Unfortunately it seems to kill the functionality of the back button in Firefox, because when you hit back, it goes to the previously clicked link… which is a lightbox, but it doesn’t appear when visited using the back button.

So, if you open 10 lightboxes, you have to hit back 10 times to get back to the previous webpage you were on.

Wow, this is by far the most elegant solution I have seen to date. Not having to include all kinds of javascript to work with a lightbox sure removes yet another layer of complexity, if not uncertainty, on the frontend. Congratulations on achieving such.

Blown away! So simple, yet so spectacularly awesome! I can’t believe how simple it seems once it’s done. I’ve been trying to make something like this for quite some time now, I guess that adventure is now conquered. 🙂

I can’t believe I never thought to make a lightbox sans javascript! Very nice idea.

My only unfortunate niggle is with how this affects the behaviour of the back button. I think users have become to familiar with usual function of the back button after using a lightbox link for this method to be totally viable.

Ok, totally blows my mind. This was a super awesome article and concept. I agree with some of the other commenters, it might be a little excessive for some projects, but the fact that it COULD be accomplished is the amazing part.

As far as Opera support….. oh, how I wish Opera would act like at least ONE mainstream browser, even if that browser were Win IE… LOL.

This is a great concept, and looks great in Safari; however, I first tried it in Opera 10 and it was a no-go. Not sure why… I see other posters have also complained about Opera. With the weight of Webkit- and Gecko-based browsers against it (and even IE), I suppose this is a (very rare) rendering bug in Opera?

Hi Jenna,
It’s an interesting thing. I like that example, it’s showed me a new CSS approach.
But in real world it’s not so useful, in fact it’s quite a hack because CSS should be primarily a styling tool. The first serious issue is that there’s no convenient method to scroll to the bottom of a lightbox that is taller than the window size and it has probably some cross browser compatibility bugs as well.
For progressive enhancement behavior and user interaction you should use JS which is designed just for that.
Useful reading here: http://www.alistapart.com/articles/understandingprogressiveenhancement/
Anyway bring us more experiments! 🙂
F.

It’s a very neat experiment, but I think there may be a problem with keyboard accessibility. When tabbing through the links, I can open a lightbox but tabbing to the close link and activating it then leaves the focus somewhere at the end of the page. So I lose where I was when I opened the lightbox and have to shift-tab to get back.

I think this might be fixed if the close link were to link back to the original link in the text, perhaps by putting ids on the links in the text?

There’s no doubt that this is seriously impressive work, but with that said, I personally think the accessibility issue (which is what this comes down to) can be taken a little too far. Although I have no stats to back this up, the amount of people who will not have Javascript enabled in their browser of choice these days will be minimal.

Am I glad I found this blog post! I’d been linked directly to the example file, and it had melted my brain for a good 10min while I was trying to figure out how you’d achieved lightboxes without :active or :focus.

For a while there I was questioning how some plain CSS/HTML was beating me!

I’d say that allowing you to cycle through the lightboxes is a feature. On a recent project I did I had to spend a lot of time getting my modal windows to be supported by the browser history. If I’d done it this way all that legwork would’ve been done for me.

First of all, just for the records,
It doesn’t work with FF2.0.0.20 on WinXP SP4

>> I’d say that allowing you to cycle through the lightboxes is a feature.
>> On a recent project I did I had to spend a lot of time getting my modal
>> windows to be supported by the browser history.
>> If I’d done it this way all that legwork would’ve been done for me.

I don’t agree… I mean…
Sometimes it could be true, sometimes not.
It depends on what the user is especting from interface.

for example when I click the back button from a normal blogpage
I expect to go back to the page I came from,
not to the previous image/content/media I watched from a link.

To be honest, I have never fallen in a web site that showed
or required the the situation you are describing.

So, I think the best solutions should be a combinations of parameters/constants that control this beaviour depending on what the web developer wants.

Changing height to min-height on #lightboxes or removing overflow:auto gets it to work in Opera – kinda. The double scrollbars are still there either way (at least until you click on a link) but at least the pop-up boxes appear. Both changes produce the same double scrollbar effect in Firefox and Safari.

Yeah, the article says that it only works in FF, Safari, Chrome, IE6, IE7 and IE8. Unfortunately Opera doesn’t work the same as the other browsers when linking to an element on the page. It doesn’t “pull” it into view if it’s off the page. There may also be other issues but I gave up testing Opera after I realised that and couldn’t find a work-around.

If anyone can think of a solution for this then please do let me know =)