Site icon Treehouse Blog

How to Create a Valid Non-Javascript Lightbox

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.

Step 1: Writing the Markup

<div id="container">
    <div id="header">
        <h1>A valid XHTML and CSS Lightbox (no JavaScript)</h1>
        <p><strong>by Jenna Smith</strong></p>
    </div>
    <div id="content">
        <h2>Click any of the links below to see it in action</h2>
        <p>Lorem ipsum dolor sit amet, consectetur <a href="#">about us</a> adipiscing elit.
        Donec massa lorem, elementum et mollis non, viverra a est. Proin nunc orci, tristique at egestas et,
        interdum ac ipsum. Nulla <a href="#">more info</a> vulputate erat ac gravida. Mauris facilisis, leo ac condimentum commodo,
        justo eros molestie dolor, a posuere orci tortor sed lacus. Suspendisse dictum, magna eu posuere tempor,
        augue diam tempor lacus, sed hendrerit nulla ante quis justo. Aliquam eget tellus risus.</p>
    </div>
    <div id="footer">
    	<p>Copyright 2009 Jenna Smith</p>
    </div>
</div>

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>:

<ul id="lightboxes">
    <li id="lightbox-about">
        <div class="box">
            <h3>About</h3>
            <p>
                Duis eros nibh, tempor sed ultricies eget, malesuada id nunc. Praesent a purus non
                risus dignissim placerat et eu dolor. Maecenas rutrum odio vitae libero sagittis a faucibus metus tincidunt.
                Praesent bibendum sagittis elit, nec convallis enim tincidunt quis.
            </p>
            <p>
                Duis eros nibh, tempor sed ultricies eget, malesuada id nunc. Praesent a purus non
                risus dignissim placerat et eu dolor. Maecenas rutrum odio vitae libero sagittis a faucibus metus tincidunt.
                Praesent bibendum sagittis elit, nec convallis enim tincidunt quis.
            </p>
            <a href="#" class="close" title="close window">x</a>
        </div>
    </li>
    <li id="lightbox-more">
        <div class="box">
            <h3>More stuff</h3>
            <p>
                Duis eros nibh, tempor sed ultricies eget, malesuada id nunc. Praesent a purus non
                risus dignissim placerat et eu dolor. Maecenas rutrum odio vitae libero sagittis a faucibus metus tincidunt.
                Praesent bibendum sagittis elit, nec convallis enim tincidunt quis.
            </p>
            <a href="#" class="close" title="close window">x</a>
        </div>
    </li>
</ul>

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):

html {
font-size: 75%;}

html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;}

body {
background-color: #f8f8f8;
font-family: arial, helvetica, sans-serif;
color: #777;
text-align: center;
font-size: 1.0833em;
line-height: 1.6923em;}

a {
color: #09F;}

h2 {
font-weight: normal;}

p {
margin: 0 0 1.6923em 0;}

#container {
width: 100%;
height: 100%;}

#header,
#content,
#footer {
text-align: left;
width: 870px;
margin: 0 auto;
padding: 40px;}

#header,
#footer {
background-color: #eee;}

#header h1 {
margin: 0;}

#header p {
margin: 5px 0 0;}

#content {
background-color: #fff;}

/* ---------------------------------------------------------- */
/* LIGHTBOXES
/* ---------------------------------------------------------- */
#lightboxes {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
list-style-type: none;
text-align: left;}

#lightboxes li {
width: 100%;
height: 9999px;
position: relative;
background: rgba(0,0,0,.5);}

#lightboxes .box {
position: absolute;
width: 400px;
height: 400px;
left: 50%;
top: 50px;
border: 10px solid #999;
margin-left: -230px;
background-color: #fff;
padding: 20px;}

#lightboxes h3 {
font-weight: normal;
font-size: 1.8461em;
margin: 0 0 0.4583em 0;}

#lightboxes a.close {
position: absolute;
top: 20px;
right: 20px;
display: block;
width: 20px;
line-height: 20px;
text-align: center;
background-color: #ddd;
text-decoration: none;
font-weight: bold;
color: #999;
font-size: 1.2em;}

#lightboxes a.close:hover {
background-color: #999;
color: #fff;}

This should all be relatively easy to understand, however I just want to go over a few areas and clarify why some elements have been given certain properties. Mainly the following lightbox styling:

#lightboxes li {
width: 100%;
height: 9999px;
position: relative;
background: rgba(0,0,0,.5);}

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:

<!--[if IE]>
<style type="text/css">
    #lightboxes .ie-bg {
    background: #000;
    position: absolute;
    z-index: -1;
    width: 100%;
    height: 100%;
    filter: alpha(opacity=75);}
</style>
<![endif]-->

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:

<div id="container">
    <div id="header">
        <h1>A valid XHTML and CSS Lightbox (no JavaScript)</h1>
        <p><strong>by Jenna Smith</strong></p>
    </div>
    <div id="content">
        <h2>Click any of the links below to see it in action</h2>
        <p>Lorem ipsum dolor sit amet, consectetur <a href="#lightbox-about">about us</a> adipiscing elit.
        Donec massa lorem, elementum et mollis non, viverra a est. Proin nunc orci, tristique at egestas et,
        interdum ac ipsum. Nulla <a href="#lightbox-more">more info</a> vulputate erat ac gravida. Mauris facilisis, leo ac condimentum commodo,
        justo eros molestie dolor, a posuere orci tortor sed lacus. Suspendisse dictum, magna eu posuere tempor,
        augue diam tempor lacus, sed hendrerit nulla ante quis justo. Aliquam eget tellus risus.</p>
    </div>
    <div id="footer">
    	<p>Copyright 2009 Jenna Smith</p>
    </div>
</div>

<ul id="lightboxes">
    <li id="close"></li>
    <li id="lightbox-about">
        <div class="box">
            <h3>About</h3>
            <p>
                Duis eros nibh, tempor sed ultricies eget, malesuada id nunc. Praesent a purus non
                risus dignissim placerat et eu dolor. Maecenas rutrum odio vitae libero sagittis a faucibus metus tincidunt.
                Praesent bibendum sagittis elit, nec convallis enim tincidunt quis.
            </p>
            <p>
                Duis eros nibh, tempor sed ultricies eget, malesuada id nunc. Praesent a purus non
                risus dignissim placerat et eu dolor. Maecenas rutrum odio vitae libero sagittis a faucibus metus tincidunt.
                Praesent bibendum sagittis elit, nec convallis enim tincidunt quis.
            </p>
            <a href="#close" class="close" title="close window">x</a>
        </div>
        <!--[if IE]>
        <div class="ie-bg"></div>
        <![endif]-->
    </li>
    <li id="lightbox-more">
        <div class="box">
            <h3>More stuff</h3>
            <p>
                Duis eros nibh, tempor sed ultricies eget, malesuada id nunc. Praesent a purus non
                risus dignissim placerat et eu dolor. Maecenas rutrum odio vitae libero sagittis a faucibus metus tincidunt.
                Praesent bibendum sagittis elit, nec convallis enim tincidunt quis.
            </p>
            <a href="#close" class="close" title="close window">x</a>
        </div>
        <!--[if IE]>
        <div class="ie-bg"></div>
        <![endif]-->
    </li>
</ul>

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:

html {
overflow-y: auto;}

…and we’re done.

Your document in it’s entirety should be similar to below:

<!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">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>XHML and CSS Lightbox</title>

    <style type="text/css">
    html {
    font-size: 75%;}

    html, body {
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;}

    body {
    background-color: #f8f8f8;
    font-family: arial, helvetica, sans-serif;
    color: #777;
    text-align: center;
    font-size: 1.0833em;
    line-height: 1.6923em;}

    a {
    color: #09F;}

    h2 {
    font-weight: normal;}

    p {
    margin: 0 0 1.6923em 0;}

    #container {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    overflow: auto;}

    #header,
    #content,
    #footer {
    text-align: left;
    width: 870px;
    margin: 0 auto;
    padding: 40px;}

    #header,
    #footer {
    background-color: #eee;}

    #header h1 {
    margin: 0;}

    #header p {
    margin: 5px 0 0;}

    #content {
    background-color: #fff;}

    /* ---------------------------------------------------------- */
    /* LIGHTBOXES
    /* ---------------------------------------------------------- */
    #lightboxes {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    list-style-type: none;
    text-align: left;
    overflow: hidden;}

    #lightboxes li {
    width: 100%;
    height: 9999px;
    position: relative;
    background: rgba(0,0,0,.5);}

    #lightboxes .box {
    position: absolute;
    width: 400px;
    height: 400px;
    left: 50%;
    top: 50px;
    border: 10px solid #999;
    margin-left: -230px;
    background-color: #fff;
    padding: 20px;}

    #lightboxes h3 {
    font-weight: normal;
    font-size: 1.8461em;
    margin: 0 0 0.4583em 0;}

    #lightboxes a.close {
    position: absolute;
    top: 20px;
    right: 20px;
    display: block;
    width: 20px;
    line-height: 20px;
    text-align: center;
    background-color: #ddd;
    text-decoration: none;
    font-weight: bold;
    color: #999;
    font-size: 1.2em;}

    #lightboxes a.close:hover {
    background-color: #999;
    color: #fff;}

    #lightboxes #close {
    background-color: transparent;
    z-index: -1;}
    </style>

    <!--[if IE]>
    <style type="text/css">
    html {
    overflow-y: auto;}

    #lightboxes {
    position: relative;}

    #lightboxes .ie-bg {
    background: #000;
    position: absolute;
    z-index: -1;
    width: 100%;
    height: 100%;
    filter: alpha(opacity=75);}
    </style>
    <![endif]-->
</head>

<body>

<div id="container">
    <div id="header">
        <h1>A valid XHTML and CSS Lightbox (no JavaScript)</h1>
        <p><strong>by Jenna Smith</strong></p>
    </div>
    <div id="content">
        <h2>Click any of the links below to see it in action</h2>
        <p>Lorem ipsum dolor sit amet, consectetur <a href="#lightbox-about">about us</a> adipiscing elit.
        Donec massa lorem, elementum et mollis non, viverra a est. Proin nunc orci, tristique at egestas et,
        interdum ac ipsum. Nulla <a href="#lightbox-more">more info</a> vulputate erat ac gravida. Mauris facilisis, leo ac condimentum commodo,
        justo eros molestie dolor, a posuere orci tortor sed lacus. Suspendisse dictum, magna eu posuere tempor,
        augue diam tempor lacus, sed hendrerit nulla ante quis justo. Aliquam eget tellus risus.</p>

        <p>Proin sollicitudin <a href="#lightbox-more">more info</a>
        elementum sem id pulvinar. Nunc vitae nulla nunc, at tempor nisi. Vivamus condimentum tempus auctor. Vivamus
        aliquet lorem at mauris rutrum vitae molestie nunc hendrerit. Pellentesque condimentum metus sed mi euismod
        lobortis id sit amet orci. Duis eros nibh, tempor sed ultricies eget, malesuada id nunc. Praesent a purus non
        risus dignissim placerat et eu dolor. Maecenas rutrum odio vitae libero sagittis a faucibus metus tincidunt.
        Praesent bibendum sagittis elit, nec convallis enim tincidunt quis. Duis vitae risus sed ipsum varius volutpat
        in in tortor. Duis nec est at mi condimentum consequat sed vitae metus. Lorem ipsum dolor sit amet, consectetur
        adipiscing elit.</p>

        <p>Lorem ipsum dolor sit amet, consectetur <a href="#lightbox-about">about us</a> elit. Donec massa lorem,
        elementum et mollis non, viverra a est. Proin nunc orci, tristique at egestas et, interdum ac ipsum. Nulla
        ullamcorper vulputate erat ac gravida. Mauris facilisis, leo ac condimentum commodo, justo eros molestie dolor,
        a posuere orci tortor sed lacus. Suspendisse dictum, magna eu posuere tempor, augue diam tempor lacus, sed
        hendrerit nulla ante quis justo. Aliquam eget tellus risus. Proin sollicitudin elementum sem id pulvinar. Nunc
        vitae nulla nunc, at tempor nisi. Vivamus condimentum tempus auctor. Vivamus aliquet lorem at mauris rutrum vitae
        molestie nunc hendrerit. Pellentesque condimentum metus sed mi euismod lobortis id sit amet orci. Duis eros
        nibh, tempor sed ultricies eget, malesuada id nunc. Praesent a purus non risus dignissim placerat et eu dolor.
        Maecenas rutrum odio vitae libero sagittis a faucibus metus tincidunt. Praesent bibendum sagittis elit, nec
        convallis enim tincidunt quis. Duis vitae risus sed ipsum varius volutpat in in tortor. Duis nec est at mi
        condimentum consequat sed vitae metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    </div>
    <div id="footer">
    	<p>Copyright 2009 Jenna Smith</p>
    </div>
</div>

<ul id="lightboxes">
    <li id="close"></li>
    <li id="lightbox-about">
        <div class="box">
            <h3>About</h3>
            <p>
                Duis eros nibh, tempor sed ultricies eget, malesuada id nunc. Praesent a purus non
                risus dignissim placerat et eu dolor. Maecenas rutrum odio vitae libero sagittis a faucibus metus tincidunt.
                Praesent bibendum sagittis elit, nec convallis enim tincidunt quis.
            </p>
            <p>
                Duis eros nibh, tempor sed ultricies eget, malesuada id nunc. Praesent a purus non
                risus dignissim placerat et eu dolor. Maecenas rutrum odio vitae libero sagittis a faucibus metus tincidunt.
                Praesent bibendum sagittis elit, nec convallis enim tincidunt quis.
            </p>
            <a href="#close" class="close" title="close window">x</a>
        </div>
        <!--[if IE]>
        <div class="ie-bg"></div>
        <![endif]-->
    </li>
    <li id="lightbox-more">
        <div class="box">
            <h3>More stuff</h3>
            <p>
                Duis eros nibh, tempor sed ultricies eget, malesuada id nunc. Praesent a purus non
                risus dignissim placerat et eu dolor. Maecenas rutrum odio vitae libero sagittis a faucibus metus tincidunt.
                Praesent bibendum sagittis elit, nec convallis enim tincidunt quis.
            </p>
            <a href="#close" class="close" title="close window">x</a>
        </div>
        <!--[if IE]>
        <div class="ie-bg"></div>
        <![endif]-->
    </li>
</ul>

</body>
</html>

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.

Exit mobile version