CSS-Plus
CSS-Plus
Play with web technologies

Create an infinite polaroid image viewer with jQuery

July 26, 2010
Attention: This article is old and the content is outdated. I've left the article here for historical purposes.

The name of the tutorial might be a bit confusing, so I'll start by clearing it up.

Infinite - Refers to the fact that if you click the "next button" on the last slide, it loops to the first image, and vice-versa with the "previous button". (Achieved with jQuery javascript) Polaroid - Refers to the look (achieved with CSS) Image Viewer - I was going to use "Carousel", however, this doesn't really slide... It fades. So "Image Viewer" found a place in the title. (Achieved with jQuery javascript)

I like image/content sliders, however, they are always so complicated: Divs within divs containing unordered lists, list items, anchor links and span tags. This Infinite Polaroid Image Viewer works on a single div containing <img> tags. The caption text is taken from <img> alt tags. Also, this is designed to look decent without CSS3 and with javascript turned off.

Let's get started.

The HTML

What exactly is needed besides the div#polaroid? Yes, you guessed it, the controls and caption area. The caption area is not necessary without javascript (since this won't work at all without it) so it would be best to inject it using javascript. It is added in the HTML below, however we will remove it at a later stage to minimize the markup.

<div id="polaroid">
    <img alt="People at a bar" src="images/image-1.jpg" />
    <img alt="Tree and Dam" style="display: none;" src="images/image-2.jpg" />
    <img alt="Puppy" style="display: none;" src="images/image-3.jpg" />
    <img alt="Clouds" style="display: none;" src="images/image-4.jpg" />
</div>
<div id="polaroid-caption">
    <a id="prev" href="#"></a>
    <a id="next" href="#"></a>
    <p class="caption"></p>
</div>

I don't think we could work with much less markup, and because of this, there really much to explain about the HTML. It's very straightforward: We will be able to cycle through the images included within the #polaroid div.

The CSS

We're going to do the obvious styling with the CSS, including some CSS3 and a fall-back in case javascript is turned off. We've added some inline styling to the images in the HTML. This is done to make sure only one image is shown if the javascript is turned off.

#polaroid {
    background: #ededed;
    margin: 0 0 0 20px;
    padding: 15px 15px 0 15px;
    width: 500px;
}
#polaroid img {
    width: 500px;
    height: 380px;
}
#polaroid-caption {
    color: #000;
    background: #ededed;
    height: 40px;
    margin: 0 0 0 20px;
    padding: 30px 15px;
    width: 500px;
}

/* Caption and controls */
#polaroid-caption a {
    color: #000;
}
#polaroid-caption p.caption {
    font-weight: bold;
    text-align: center;
}
#prev,
#next {
    display: block;
    height: 24px;
    width: 14px;
}
#prev {
    background: url(../images/prev.jpg) no-repeat left top;
    float: left;
}
#next {
    background: url(../images/next.jpg) no-repeat left top;
    float: right;
}

/* css3 */
#polaroid {
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    -moz-border-radius-topleft: 10px;
    -moz-border-radius-topright: 10px;
    -webkit-border-top-left-radius: 10px;
    -webkit-border-top-right-radius: 10px;
}
#polaroid-caption {
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
    -moz-border-radius-bottomleft: 10px;
    -moz-border-radius-bottomright: 10px;
    -webkit-border-bottom-left-radius: 10px;
    -webkit-border-bottom-right-radius: 10px;
}

The jQuery Javascript

Alright, now it's time for the cool part javascript:

$(window).load(function() {
    $("#polaroid").after(
        '<div id="polaroid-caption"><a id="prev" href="#"></a><a id="next" href="#></a><p class="caption"></p></div>'
    );

    $("p.caption").text($("#polaroid img:visible").attr("alt"));

    // Next controls
    $("#next").click(function() {
        if ($("#polaroid img:last").is(":visible")) {
            $("#polaroid img:visible").fadeOut(function() {
                $("#polaroid img:first").fadeIn();
                $("p.caption").text($("#polaroid img:visible").attr("alt"));
            });
        } else {
            $("#polaroid img:visible").fadeOut(function() {
                $(this)
                    .next()
                    .fadeIn();
                $("p.caption").text($("#polaroid img:visible").attr("alt"));
            });
        }
        return false;
    });

    // Previous controls
    $("#prev").click(function() {
        if ($("#polaroid img:first").is(":visible")) {
            $("#polaroid img:visible").fadeOut(function() {
                $("#polaroid img:last").fadeIn();
                $("p.caption").text($("#polaroid img:visible").attr("alt"));
            });
        } else {
            $("#polaroid img:visible").fadeOut(function() {
                $(this)
                    .prev()
                    .fadeIn();
                $("p.caption").text($("#polaroid img:visible").attr("alt"));
            });
        }
        return false;
    });
});

What it's "saying" is:

  1. firstly, make sure that p.caption's text is that of the visible image's alt attribute.
  2. When "next" is clicked, if the last image is visible, fade out this image and once that is done, fade in the first image and make sure that p.caption's text is that of the visible image's alt attribute.
  3. Else, if this is not the case, fade out the visible image and once this is done, fade in the next image and and make sure that p.caption's text is that of the visible image's alt attribute.
  4. Return false makes sure that the anchor link doesn't act as a normal link.

The "previous" controls work the same, but in reverse.

Pretty cool, right? I find it very simple, and the simplicity makes it very nice to work with.

I hope you enjoyed the tutorial and if you have any questions or anything to say, feel free to leave a comment.

Demo