Semantic CSS3 Lightboxes

May 26 2010 by Alexander Dawson | 45 Comments

Semantic CSS Lightboxes

The rise of jQuery, MooTools, and JavaScript frameworks has given many web designers a new lease on life, adding more unique functionality into their sites.

Most notably among the various cool and interesting features you can find being injected into a design is the humble lightbox (modal window).

If you’ve ever come across a link or image which — upon clicking — increases in size and where the rest of the screen gets "shaded" to focus on the content, you’ll know what I’m talking about.

This tutorial aims to showcase a method of displaying content based on the lightbox, which is web accessible and (excluding Internet Explorer) will require no scripting at all. Sound like fun? Well, let’s explore the subject further!

Demonstration

Click the preview image below to see a live demonstration.

Demonstration

What About Scripting?

There’s a lot to be said about the benefits of using client-side scripting for this. While we are certainly not in the cut-and-paste era that leads to the kind of crimes against JavaScript many coders would like to see punished, we do, to this day, still have an uncomfortable reliance on scripts and frameworks in order for our websites to function.

Perhaps it seems a little hypocritical in this instance for me to critique the use of scripting (as Internet Explorer users will require scripting enabled to use this functionality), but like all things, we sometimes need to compromise our code to ensure compatibility (especially with that browser)!

Why Not Just Use JavaScript?

In the sense of the current scripting frameworks, I’m not going to say that they are inherently bad because the likes of jQuery often gracefully degrade with good levels of success — you guys can put away the knives and flame-lit torches now!

However, the sad facts are that, due to security issues, widespread abuse and the intrusive potential of client-side scripting, it’s quite easy to understand why a large number of people do not (or cannot) make use of scripting.

Therefore, a solution is required. And hopefully for you CSS3 fans, you’ll find this simple, easy-to-use code to be a welcome improvement.

Browser Support of this CSS Lightbox

To give you a quick introduction before we begin producing the code itself, it’s worth mentioning that I’ve tried the code in a variety of browsers and can say for sure that it works in all recent versions of Mozilla Firefox, Google Chrome, Apple Safari and Opera (which is all great news).

With a little bit of unobtrusive scripting that replicates the CSS3 techniques, it’ll also run smoothly within IE 6, 7 and 8.

The other fantastic news is that current test versions of IE9 support CSS3, so this may very well be the best JavaScript-free solution there is in the near future.

Browser Support of this CSS LightboxInternet Explorer is the usual culprit when it comes to lacking in standards support.

Magic Markup!

To begin our quest for a much more compatible lightbox, the first thing we need is some general HTML markup.

Much of the below won’t surprise you in the slightest as it’s pretty standard. However, for this example, and to showcase how durable this cool method is, we’ll produce three individual lightboxes.

One will be for an image, one will be for a block of scrollable content and the final one will hold a YouTube video. What more could you ask for?

To begin, let’s create the basics and have three fragment links which will go to the correct lightbox (you’ll learn how a bit later on).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>CSS Lightbox</title>
</head>
<body>
<h1>CSS Lightbox</h1>
<p>You can use this fantastic solution to create lightboxes for not just <a href="#image" title="Image Lightbox">images</a> but rich, semantic <a href="#content" title="Content Lightbox">content</a> and <a href="#video" title="Video Lightbox">video's</a> as well!</p>
</body>
</html>

Magic Markup!Not much going on at this stage, a simple HTML document with extra links.

So far, things are pretty simple; you have a heading and paragraph with some links that, upon clicking, will currently do nothing.

The next stage in the process, however, is all important.

We need to add the container for each lightbox to appear within and give them their appropriate values.

To give you an idea as to how each of the three lightboxes work, you’ll need to examine (and add) the code into your source code editor.

To better understand how it works, let’s talk about each item individually.

<div class="lightbox" id="image">
<div class="w300 h60">
<img alt="Six Revisions" height="98" width="255" src="logo.jpg />
</div>
<p class="close"><a href="#" title="Close This Image Lightbox">Close <span>X</span></a></p>
</div>

Each lightbox you wish to provide will require a div element container that contains the id attribute you wish to link too. That id will reference what you’ll need to attach to the href anchor to start the navigation process, not forgetting you’ll also need the lightbox class value on each you include.

Are you with me so far? Good!

Once you have the container that references the lightbox, you’ll need to include both a div (which will hold the lightbox content and will have the width and height declared through class values like in the above) and a paragraph with an anchor to act as the "shader".

Using the above source code, you should find yourself with a working lightbox that contains an image. In this example, I used the Six Revisions logo.

You can indeed link to any image of any size, taking into account the viewport space available.

A Little Bit More About the "Shader"

To better understand how this gets its visual appearance, the secondary div layer works independently from the close anchor which filters in the background. It’s essentially a cascading/tiling effect at work.

The first lightbox has appeared, and it contains an image.The first lightbox has appeared, and it contains an image.

If you look at any modern lightbox, the most common characteristic you will see is that you have a semi-transparent layer which covers over the rest of the page drawing focus to the lightbox content. Upon clicking on this layer, it will return you to the page. This is the very reason why each lightbox requires a closing anchor.

What Should the href Value Be?

The great thing is that you could even link the href to another lightbox if you wanted it to do something other than close (using the null fragment link).

What Can the divs Contain?

As for what’s inside the div, it’s entirely up to you. You can use any block or inline elements (the lightbox will house any HTML element).

In the first example, we had an image; let’s add some content within the code:

<div class="lightbox" id="content">
<div class="w60p h400 scroll">
<h2>Your Content Goes Here!</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent quis felis suscipit tellus euismod varius quis ut nibh. Curabitur in ante nunc, vitae venenatis dui. Phasellus egestas ipsum in ipsum suscipit volutpat. Etiam eu nibh eros. Sed dolor ligula, tincidunt vitae elementum vitae, pharetra vitae eros. Cras risus lectus, aliquam vitae condimentum id, feugiat eu nisi. Cras eu sem erat, eget ultrices enim. Suspendisse feugiat fringilla massa at convallis. Quisque tincidunt, diam quis facilisis volutpat, purus orci rutrum leo, id dapibus tellus ante vel mauris. Quisque posuere, tortor in laoreet hendrerit, ipsum sem molestie nunc, et ultrices erat nulla sed dui. Donec sit amet mi sapien. Maecenas fermentum nulla eu ligula dictum id elementum nisi commodo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In ac massa quam. Suspendisse nibh nibh, condimentum a porttitor a, placerat in lorem. Sed sit amet elit eget magna condimentum posuere volutpat a neque.</p>
<p>Sed dignissim viverra neque, sit amet lobortis elit luctus ac. Proin placerat varius quam eu molestie. Pellentesque vel ante quis metus auctor convallis. Duis mattis risus ac tortor luctus in semper sem fringilla. Vestibulum consectetur iaculis risus vel rutrum. Nam scelerisque gravida felis quis egestas. Mauris vehicula nisl quis felis bibendum nec placerat neque dictum. Donec erat tortor, venenatis id consequat ut, dictum nec enim. Ut ultrices eros vel diam pulvinar aliquam. Phasellus non nisi vitae ligula imperdiet dapibus eleifend sed neque. Morbi gravida dignissim turpis eu auctor. Morbi pellentesque urna vitae nunc dictum elementum. Aliquam erat volutpat. Aenean urna nibh, pretium ut accumsan ut, luctus eget nibh. Nulla sollicitudin fermentum turpis eget rutrum. Integer dignissim dui turpis. Morbi metus libero, suscipit blandit dignissim aliquam, sodales non mi. Proin id augue odio, sit amet gravida mauris.</p>
<p>Proin a dignissim orci. Nam nec urna nisi, in blandit lorem. Nulla cursus ornare rhoncus. Nunc lectus orci, tristique et aliquet sed, venenatis et felis. Nullam sodales orci at est pharetra nec aliquam risus scelerisque. Nullam varius, nisi ut sagittis scelerisque, nulla mauris tempus magna, quis pellentesque sem erat a diam. Cras lectus est, dictum ut consequat ut, adipiscing sit amet sapien. Curabitur tincidunt varius gravida. Quisque augue sem, commodo sed molestie venenatis, cursus vehicula lorem. Praesent scelerisque, tortor a euismod malesuada, ipsum ligula semper odio, ultricies molestie sapien metus condimentum felis. Vivamus hendrerit gravida interdum. Fusce at purus eu orci laoreet lobortis. Aliquam cursus mi at tellus fringilla dictum. Sed nec libero dolor. Integer nec neque at mi malesuada tincidunt.</p>
</div>
<p class="close"><a href="#" title="Close This Content Lightbox">Close <span>X</span></a></p>
</div>

For all whom understand the value of dummies, some Lipsum content is added.For all whom understand the value of dummies, some Lipsum content is added.

Add a YouTube Video

And to round things off even further, let’s add a YouTube video into the mix:

<div class="lightbox" id="video">
<div class="w640 h386">
<object type="application/x-shockwave-flash" width="640" height="385" data="http://www.youtube.com/v/bsGEWHNJ3s8"><param name="movie" value="http://www.youtube.com/v/bsGEWHNJ3s8" /></object>
</div>
<p class="close"><a href="#" title="Close This Video Lightbox">Close <span>X</span></a></p>
</div>

Video on demand, that'll work in the lightbox too! Pretty cool isn't it?Video on demand, that’ll work in the lightbox too! Pretty cool isn’t it?

At this stage, we have completed the entire HTML file that this demonstration will use.

If you want to preview the results in your web browser, you’ll notice that as well as the heading and paragraph, there will now be the three pieces of information on the page (the image, the content block and the video), each with a "Close" link right below it.

Right on :target

At this stage, you’re probably wondering how we’re going to ensure that only the right content appears when it’s needed. And that’s a good question! We are going to use a cool CSS3 pseudo-selector called :target (which styles based on the anchor).

Perhaps you’ve come across the :target selector before, perhaps not. Basically, it cleverly allows you to apply specific style to an element if its id matches the fragment identifier, which is the hash (#) symbol followed by text usually found in page bookmarks. For example: index.html#content (you’ll see it in the address bar).

So, without any further ado, it’s time we began formatting our lightbox to perform the required task whenever this fantastic selector is activated.

You now know why we give the three links in the first piece of code those unique URLs (and gave each div a matching id).

Fragment links are best indicated by the # (hash) character at the end of a URL.Fragment links are best indicated by the # (hash) character at the end of a URL.

For the following piece of code, I’ll provide everything you need using a style element within the <head> of the document.

Generally, this is considered bad practice because all CSS styles should be separated from the structure. However, as this is simply an example and it works unobtrusively, you can easily place all of the stylistic code in an external file. For simplicity, I’ll keep it in-line.

To begin, we’ll start by adding in the easy-to-follow snippets of code such as removing the padding and margins from the document. Also, we’ll hide the lightboxes off-screen until they’re required using some absolute positioning and negative margins.

<style type="text/css">
html, body {
  height: 100%;
  overflow: hidden;
  width: 100%;
  margin: 0;
  padding: 0;
}
body { overflow-y: auto; }
.lightbox {
  left: -999em;
  position: absolute;
}
</style>

Note: It is entirely possible for you to hide your three lightboxes when they’re not in use using the property display: none. However, as this can affect how some screen reading software will interact with your page, I’ve used negative positioning to get the same effect.

With lightboxes offset, things disappear.With lightboxes offset, things disappear.

Upon refreshing your browser at this stage, you’ll notice that the three previously visible lightboxes will be hidden, which is great.

However, when you click on the links, nothing happens! Don’t worry, your lightbox isn’t broken.

All we need to do is add in the code to activate the two layers (the “close this” lightbox anchor, that gives the fade effect and the lightbox content itself).

.lightbox:target { bottom: 0; left: 0; right: 0; top: 0; position: absolute; }
.lightbox:target .close a { background: rgba(0, 0, 0, 0.75); bottom: 0; left: 0; right: 0; top: 0; position: absolute; z-index: 1; }
.close span { color: #FFFFFF; font-size: 2em; text-indent: 0; position: absolute; right: 0.5em; top: 0.5em; }
.close {text-indent: -999em;}

Keeping things simple, the above code will span the lightbox to every corner of the browser viewport using absolute positioning.

The second line of code will reinforce this code on the anchor itself and will give it a z-index (for priority over the other stuff on the page) and a background which makes use of opacity in browsers that natively support CSS3 alpha transparency.

The third line will use the span element on the "close" button to give it some emphasis for people to know that clicking in the anchor closes the lightbox.

The last line will hide the text in the faded section (for full effect).

Note: It’s worth pointing out that if your content scrolls and you wish the lightbox to follow the scroll action, you can replace position: absolute with position: fixed, however IE6 will not support it. For the example, I’ve used absolute positioning for simplicity and to showcase its potential usage.

Now when you click on a lightbox link, the transparency effect flourishes.Now when you click on a lightbox link, the transparency effect flourishes.

If you refresh your browser with the above code, you’ll notice upon clicking any element that you get that amazing faded effect which will span the entire content. And you should also have a neat little "X" button in the top-right corner just to help reinforce the effect upon clicking outside of the lightbox.

The problem now is we need to get the lightbox contents itself positioned correctly and looking great on the screen.

So below, you’ll find the last bits of CSS to align the content and offset it based on the width of the contents specified.

.lightbox:target div { background: #FFFFFF; position: absolute; left: 50%; top: 50%; z-index: 99; }
.w60p { margin-left: -30%; width: 60%; } .w300 { margin-left: -150px; width: 300px; } .w640 { margin-left: -320px; width: 640px; }
.h60 { height: 60px; margin-top: -30px; } .h400 { height: 400px; margin-top: -200px; } .h386 { height: 386px; margin-top: -193px; }
.scroll { overflow-y: scroll; padding: 0 1em; }

If you refer back to the HTML code, you’ll see that each lightbox container has class values such as w300 (for width 300px) or h400 (for height 400px) or w60p (for width 60%).

The values for each lightbox were simply calculated by measuring the width and height of the contents required and then setting the container width and height to match the dimensions.

Take for example the image we used: As that had specific width and height needs, a specific width and height was applied to the lightbox container, and for each, a negative margin for half that value was given to give it accurate centering.

Note: You may have noticed that a scroll class was also added to match the width and height classes for each lightbox.

Simply put, if you have lots of content within the container and you give it a fixed width and height, the scroll mechanism will allow it to overflow with scroll bars attached. Lovely!

Adding the next bundle of code will properly align the lightboxes content.Adding the next bundle of code will properly align the lightboxes content.

Now try refreshing the page again and — Voila! — just like magic, whenever you click one of the links, its content will load in a container, in the center of the screen.

And the fantastic thing is, it will look and function like any other lightbox. Clicking inside the lightbox will act normally, but clicking outside of it will restore the main screen (and thereby hide the lightbox contents as they’re not the fragment).

If you use Firefox, Chrome, Safari or Opera, this code will work perfectly and is a 100% pure CSS way of implementing a lightbox.

But for Internet Explorer, we (as usual) have compatibility issues to deal with!

Tip: Just imagine what you can do with these target lightboxes: You could have anything from the content shown above, right through to setting the width and height of the container to 100% and have a literal different "page" appear with overflow enabled on a single page web design. Woot!

Compatibility Crisis

Without going into a great deal of detail, the below JavaScript code has been produced to deal with Internet Explorer’s lack of support for :target (this could well be the first effective and simple solution for this issue).

As with the style, I’ve attached the content inline using <script> tags in the header, but it’s entirely graceful and can appear in an external file.

As long as the script is placed below the <style> element, you shouldn’t encounter any issues in regards to the emulation of the code.

<script type="text/javascript">
<!--
 	/*@cc_on @if (@_jscript_version > 5.6)
 	function bootup(){
 	var tds = document.getElementsByTagName("a"); lightbox();
 	for( var x=0; x < tds.length; x++ ){tds[x].onclick = function(){setTimeout(lightbox, 1);};}
 	}
 	function lightbox(){
 	var counted = document.getElementsByTagName("div");
 	for( var x=0; x < counted.length; x++ ){ if ( counted[x].className == "boxfocus" ) { counted[x].className = "lightbox"; } }
 	if (location.hash.substr(1) == "") {} else { document.getElementById(location.hash.substr(1)).className = "boxfocus"; }
 	}
 	window.onload=bootup;
 	@end @*/
 	// -->
</script>

Keeping the above code as simple as possible, it makes use of conditional comments (for JavaScript) to ensure you are using Internet Explorer (hence why it references Jscript) thereby ensuring the code will not interfere with good browsers which render correctly.

When IE is verified, and the page loads, the bootup function monitors whenever an anchor is clicked.

When this event is triggered, the lightbox function is activated and it simply applies a set of classes to the div that matches the hash (#) in the address bar (fragment link), while restoring all other lightbox instances back to the default.

Essentially it says "You’re using IE? OK. You clicked a link or loaded a page? OK. The link clicked references a lightbox? OK, let’s set that in motion and reset any others which may be active".

If you’re not too JavaScript-savvy, it may not make a lot of sense, but the code requires no user maintenance and if you use the code, you’ll just have to trust me that it’ll do the job. Except for those classes to be applied, which have the alternative to the :target stuff, we’ll need to add these into the style in the header.

And to overcome IE’s lack of opacity support, we’ll add a transparent repeating PNG image in its place.

.boxfocus { bottom: 0; left: 0; right: 0; top: 0; position: absolute; }
.boxfocus div {background: #FFFFFF; position: absolute; left: 50%; top: 50%; z-index: 99; }
.boxfocus .close a { background-image: url('trans.png'); bottom: 0; left: 0; right: 0; top: 0; position: absolute; z-index: 1; }

Those of you with eagle eyes may have noticed that the properties of the boxfocus classes, which sit in place of those using the :target pseudo, contain mostly the same properties and values as their counterparts. So you may well ask: Why not group them together?

While it may seem like a smart idea to reduce repeating code, unfortunately the default behaviour for IE and other browsers is that unknown or invalid code (as it would appear to IE) should be totally ignored and deleted. Which means, if grouped, it wouldn’t work, so we need the repeated CSS as a separate entity.

With a bit of caring JavaScript, Internet Explorer will work like any other browser.With a bit of caring JavaScript, Internet Explorer will work like any other browser.

If you now refresh the page again and open it in Internet Explorer, you will find that the lightbox should now work properly in that browser.

It may not be a perfect solution to require extra CSS and some conditional JavaScript to work the mojo, but alas, this isn’t a perfect world, so we must use it to keep things as compatible as possible.

On the bright side of things, Internet Explorer 9 has full support for target so in the future, none of that extra code will be needed.

Setting Standards

And on that note, the example is complete.

  • It’s totally semantic: with div containers and the use of any HTML elements you wish within the container
  • It’s accessible: it’ll work with screen readers
  • It’s not as dependent on scripting as the jQuery solutions and you can bookmark their behaviour
  • And — all things considered — it’s more graceful in that the future looks good for the selectors’ widespread browser support without the need of any scripting

Get Involved with CSS3. Please.

Hopefully this tutorial will inspire you to get involved in testing modern standards like CSS3 because many of these elements already have basic native support.

While there is a real need at this time to make things gracefully degrade (and this option certainly can achieve that), it’s worth highlighting that the potential for the :target pseudo-class goes far beyond lightboxes: It could remove the future need for JavaScript in single-page websites, content swapping, and other process-intensive functions.

While the need for workarounds (like the JavaScript we needed to use) won’t disappear overnight, the future of web standards is pretty bright!

Download

Related Content

About the Author

Alexander Dawson is a freelance web designer, author and recreational software developer specializing in web standards, accessibility and UX design. As well as running a business called HiTechy and writing, he spends time on Twitter, SitePoint’s forums and other places, helping those in need.

45 Comments

Joshua Chase

May 26th, 2010

What a fantastic how to. I can’t wait to try this out. I think I know what I will be doing this afternoon. Great write up!

Rich

May 26th, 2010

If you set css transitions for the lightbox you could easily make it fade in and out…

esranull

May 26th, 2010

very good tuts thanks a lot

Gabri

May 26th, 2010

Very Nice :)

i think you have a small error in the article you said

“It is entirely possible for you to hide your three lightboxes when they’re not in use using the property display: none. However, as this can affect how some screen reading software will interact with your page, I’ve used negative margins to get the same effect.”

.lightbox { left: -999em; position: absolute; }

it`s not Negative margins it`s negative positioning

Adam

May 26th, 2010

This is really nice, but all your content is in the same html file – I can’t see that working with larger images (file size). When you use JS lightbox, you point to the external file.

mtrang

May 26th, 2010

Can’t wait for HTML5 and CSS3 to be completely supported by all browsers.

Good tutorial.

Alexander Dawson

May 26th, 2010

@Rich: Indeed you can, you could also use fun effects like rounded corners, box shadow and other effects to make it fancier too! What I provided offers something simple that can be enhanced. After all, the content of the lightbox is provided within a single DIV that can be easily targeted for style.

@Gabri: Well caught, that’s indeed what I meant!

@Adam: Actually, there is a workable way around this using CSS, you could attach the image to the element itself using the background-image property (for the target: element). As pseudo’s are only accessed when required (like :hover), it will therefore load the image only when the target is put into focus. Though if you do this I highly recommend you provide a paragraph of text (positioned somewhere close to the image visually and structurally) to act as alternative content (for those with accessibility issues).

Patrick

May 26th, 2010

An interesting concept, but I’m not too crazy about the User Experience once you click the back button within the browser (probably the most used button in the browser).

Roy Reed

May 26th, 2010

Very clever!

One small problem – in Firefox (3.6.3, WinXP) when you click the X to close the modal window, vertical and horizontal scrollbars appear and you have to click again to close the window. If you click on the shaded background the scrollbars appear momentarily, then disappear with the window.

Alexander Dawson

May 26th, 2010

@Patrick – I agree, but unfortunately the inconsistencies are unavoidable as it’s down to poor browser implementation on behalf of IE and Opera. I reported the bug to both months ago but we’re still awaiting a permanent fix.

Roy: What a strange quirk indeed! I’m guessing there’s a workaround, though I do wonder if perhaps we may have found a bug in Firefox (as the code seems accurate and runs without issue in other browsers).

This is all part of the fun of experimenting with new techniques… pushing code to the limit!

Vladimir

May 26th, 2010

Great informational article, I might need this some day…
Thanks :)

Daniel

May 26th, 2010

@Roy: set .lightbox class the property “overflow” to “hidden”

Scott Corgan

May 26th, 2010

Boy, if we could just politely ask Microsoft to quit dragging their feet, we may finally have a web that makes sense.

But, until then, let’s just pull out our hair while we spend extra hours making our code work, and look ugly, in IE…

louis gubitosi

May 26th, 2010

This is great… I’m in the middle of making a new site that includes a filterable portfolio, jquery scroll, jquery fade and I also wanted to include lightbox feature for images but all of the scripts were conflicting and I could only get some to work at a time.

This new method is working great so far. I haven’t tested yet, but I’m assuming this also works with Flash? Great tutorial Alexander!

kevin

May 26th, 2010

Same as Patrick, the use of back button is getting you back to the lightbox, no good for ue.

Greg

May 26th, 2010

I like this a lot. In fact, I was considering implementing CSS 3 lightboxes in a site I’m building right now, but then I tested the demo in IE6. For whatever reason, the content in the lightbox loads all the way up in the top left corner of the screen (with about 75% of the content being invisible, because it loading past the top left corner). My gut instinct tells me this is something that can be changed by altering the positioning in the IE6 script. I wish I knew more about javascript so that I could help. At any rate, it’s a very promising technique! I just wish IE6 would go away.

Young

May 26th, 2010

I guess Roy beat me to commenting on that error…
But I also don’t like that it registers the lightboxed page in your browse history. Not sure if that can be fixed without javascript, but it definitely loses the “true pop-up”ness.

Cool technique though.

Young

May 26th, 2010

Darn I guess I should read the comments more carefully cuz Patrick beat me to that too.

Mato

May 26th, 2010

Actually you could also use hidden checkboxes or radio buttons with the selected pseudo class instead of the target pseudo class. This way the URL doesn’t get changed and the history doesn’t get messed up.

http://www.thecssninja.com/demo/futurebox/v3/

D A

May 26th, 2010

Useful article – thank you.
There is a minor (major for IE) problem: if the main page content is long enough (so the vertical scrolling is required) then the faded section covers visible part of the main page only and, apparently, it moves up when main page is scrolled down. For IE8 it’s even worse: when you click the link to open “lightboxed” section the main page scrolls all the way down so you are looking at non-faded lower part of main page. HTH.

Matt

May 26th, 2010

Lovely CSS-only solution, Alex. Great work!

I wonder if there’s a way to centre the lightbox content without having to manually add those ‘w’ and ‘h’ classes? That would be really swish. I know vertical centring with arbitrary widths/heights is tricky though. Maybe using display: table, display: table-cell, and vertical-align: middle would work?

Alexander Dawson

May 26th, 2010

I have a little fix here for everyone which may be useful:

By adding the below code (as appropriate) into the existing CSS, you can not only fix the Firefox issue (of clicking on the X) but that of scrolling content in the various browsers! It effectively “fakes” fixed positioning in such a way that it also overlays the scrollbars thereby ensuring a long page of content doesn’t affect how it works. Hope it’s useful!

html, body { height: 100%; overflow: hidden; width: 100%; }
body { overflow-y: auto; }

David Wheatley

May 27th, 2010

Great CSS solution, particularly useful if anyone has conflicting scripts. I usually use jQuery for the Lightbox effect as i really like the smooth animated transitions, however, recently I’ve been looking for a solution that does not slow down the loading time – this is it!
Thanks

vp

May 27th, 2010

Nice Work, keep it up !! And also pls chk this source page in IE6 needs some fix,….

hollsk

May 27th, 2010

@vp
“And also pls chk this source page in IE6 needs some fix,….”

I think it’s generally safe to say that if a tutorial has “CSS3″ in the title, it’s unlikely to work particularly well in IE6.

Chris Heilmann

May 27th, 2010

Calling a solution that does not work for keyboard users accessible is just not understanding basic accessibility – keyboard users cannot access the links to open the lightbox in the first place.

Also, the standard way of getting rid of a modal dialogue is to press the ESC key – after shifting the focus. This is once again using new technology to half solve a problem that has been solved in the past.

An answer like the last one just pains me. If CSS3 means older browsers do not get support then they should not get the effect, period. This is what progressive enhancement was about for years now and lead to usable, clever solutions.

Our goal should be to make it easy for the end user – not to use a certain technology.

visualpro

May 28th, 2010

Nice, but it Breaks the back button in Safari

Alexander Dawson

May 28th, 2010

@Chris: I agree with you that accessibility is exceptionally important, however I was able to both open and close the lightbox using my keyboard (alone). In such cases where things can be made more accessible, I entirely support using unobtrusive scripting to ensure both compatibility and ease of use for the end-user.

I firmly believe that this method offers a greater user-experience for the 8% (approx) of people who cannot make use of scripting and therefore it serves as a solid backbone to build upon.

Rilwis

May 28th, 2010

Very nice effect and article. I really love the way you use CSS to create light box effect. Thanks for sharing a cool technique.

Smashy Design

May 31st, 2010

Cool stuff mate. Thanks for sharing…

ocean

June 1st, 2010

I like you post. Well done.
thanks for your sharing advanced CSS3 technology.

kodes

June 8th, 2010

Getting my hands on all the font types was the main stumbling block for me and as such I have tried using SiFR, Cufon and TypeKit, the @font-face kits at Squirrel will certainly help me to do so much more, great article.

My future web design projects will definetly benefit.

Cheers

Tim Holmes

Tomas

June 14th, 2010

Nowadays you here a lot of accessibility and semantic content etc. But say you for example have hidden lightboxes with content that Google have indexed and you arriving from there, it become actually harder to find where the text really exists. Why is it important to make hidden content accessible?

richphitzwell

September 21st, 2010

Awesome. I still have a few bugs with ie9 but compared to any is version I have seen this is so much quicker. I have Google maps loading on a few sites and normally the delay is about 10s this is almost instant. Thank you

richphitzwell

September 22nd, 2010

@Thomas
This issue is not new and has been around for years. There are many workarounds to force Simone who is accessing a child frame from Google into the parent frame

richphitzwell

September 23rd, 2010

Actually im having an issue with the width. If I do this it works fine in ff and chrome but not in ie. If I keep it the way you specify then in all browsers it pushes the left side to center. What am I doing wrong?
.lightbox { left: -999em; position: absolute; }
.lightbox { left: -999em; position: absolute; }
.lightbox:target { bottom: 0; left: 0; right: 0; top: 0; position: absolute; }
.lightbox:target .close a { background: rgba(0, 0, 0, 0.75); bottom: 0; left: 0; right: 0; top: 0; position: absolute; z-index: 101; }
.close span { color: #FFFFFF; font-size: 2em; text-indent: 0; position: absolute; right: 0.5em; top: 0.5em; }
.close {text-indent: -999em;}
.lightbox:target div { background: #FFFFFF; position: absolute; left: 5%; top: 50%; z-index: 200; }
.w60p { margin-left: -200px; width: 400px; } .w300 { margin-left: -400px; width: 800px; } .w900 { margin-left:-450px; width: 900px; }
.h60 { height: 500px; margin-top: 10px; } .h400 { height: 600px; margin-top: -300px; } .h386 { height: 386px; margin-top: -193px; }
.scroll { overflow-y: scroll; padding: 0 1em; }
.boxfocus { bottom: 0; left: 0; right: 0; top: 0; position: absolute; }
.boxfocus div { background: #FFFFFF; position: absolute; left: 50%; top: 50%; z-index: 101; }
.boxfocus .close a { background-image: url(‘trans.png’); bottom: 0; left: 0; right: 0; top: 0; position: absolute; z-index: 101; }
/* lightbox created by http://www.hitechy.com, thank you! */

richphitzwell

September 23rd, 2010

*I figured out what I did wrong with IE, I forgot to change the box focus to 5% as well, my bad. I must have other code that is screwing up the width. Go ahead and delete both this comment and the other comment prior to this. Im happy with it being slightly offset. Thanks for the great code man.

richphitzwell

October 19th, 2010

Found one issue, on smartphones such as droid, scroll doesnt work on content in your demo.

venkat

December 1st, 2010

good one

Luca

January 14th, 2011

Would it be possible to apply CSS3 animations to simulate a fade effect? Just for a visual implementation.

Andrew Margolin

May 3rd, 2011

Just so you know the video pop up doesnt work in ie9. If you know of any lightbox’s that work with video in ie9, please let me know :)

Jonathan

June 27th, 2011

Hi,
I love your code for the lightbox. It fits seemlessly into my page. Just one question. If I wanted to show the lightbox from javascript code, how would I go about doing that?

Robert Downey

August 29th, 2011

I found this tutorial fun and easy to understand even though I am not a coder. One wuestion I have is, if I wanted to take this to the next level and make it into a slideshow of sorts with a simple next and previous buttons to cycle through the shots, how would I do that?

I am running visual lightbox right now, it looks great but it is slow. can you help me understand. I learn fast from samples, but don’t know where to start. you can email me or reply here. Thanks!! Great Code!!

Elodie

October 20th, 2011

Hello,
It works perfectly !
Just one little problem : if I introduce a video in one of these lightbox different of a youtube video :
I mean a video file which is on my website, and I use the code description
When I close the lightbox, the video is still running !
There is no compatibility ? Or do you have an issue ?

Tom

November 18th, 2011

The video continues to play even after you close the lightbox! You have to keep hitting the back button to make it stop. Unfortunately, it’s not worth using this for video. And even with the other lightboxes, when you hit the back button, you don’t go to the original page you opened but to all previously open lightbox pop-ups. Great concept but very impractical and potentially annoying to website visitors.

Leave a Comment

Subscribe to the comments on this article.