A tutorial about how to create some neat scrollable photo booth strips and integrate Lightbox 2 and customize it in order to make it responsive and touch-device friendly.

In today’s tutorial we’ll show you how to create some cute looking photo strips and integrate Lightbox 2, one of the most popular and widely used lightbox scripts. The idea is to show some photo strips and make them navigable by scrolling with the mousewheel. When clicking on a picture we will show the larger version using jQuery Lightbox 2. We will also optimize it for touch devices.

Please note that we might use some new CSS properties that don’t work in older browsers.

The amazing images are by talented Sherman Geronimo-Tan and they are licensed under Creative Commons Attribution 2.0 Generic (CC BY 2.0).

Lightbox 2 is by Lokesh Dhakar and you can find the script and examples of usage here: Lightbox 2

The Markup

Let’s first write the HTML for the four photo strips. Each photo strip will consist of a main container with the class pb-wrapper. The strip itself is an unordered list and we will wrap it into the pb-scroll division. At the bottom of the photo strip we’ll add the title of the strip:

<div class="pb-wrapper pb-wrapper-1"> <div class="pb-scroll"> <ul class="pb-strip"> <li> <a href="images/large/1.jpg" rel="lightbox[album1]" title="Spring"> <img src="images/small/1.jpg" /> </a> </li> <li> <a href="images/large/2.jpg" rel="lightbox[album1]" title="Sunshine"> <img src="images/small/2.jpg" /> </a> </li> <li> <!--...--> </li> <!--...--> </ul> </div> <h3 class="pb-title">Pure Serenity</h3> </div>

Each photo strip wrapper will also have a position class like pb-wrapper-1, pb-wrapper-2, etc. We will then define custom positions, heights and rotations for each.

As you can see, we use the “rel” attribute for the Lightbox 2 script. Here we will add the path to a larger version of the thumbnail.

Let’s take a look at the style.

The CSS

The wrappers for the photo strips will have a fixed position. This will help us define a height relative to the screen size. We’ll add some nice box shadow and a textured repeated background image to make it look more like paper:

.pb-wrapper { position: fixed; background: #fff url(../images/paper.jpg) repeat center bottom; width: 170px; margin-top: 10px; padding: 20px 10px 100px; overflow: hidden; box-shadow: inset 1px 0 0 3px rgba(255,255,255,0.6), 0 1px 4px rgba(0,0,0,0.3), inset 0 0 20px rgba(0,0,0,0.05), inset 0 -25px 40px rgba(0,0,0,0.08); }

The large padding at the bottom will leave some space for the title of the photo strip.

Let’s use the :after pseudo-element for the little circle that will indicate to the user that he needs to scroll with the mousewheel, and the :before pseudo-element in order to add some extra shadow effect to the left side of the strip, just for a subtle effect:

.pb-wrapper:before { content: ''; position: absolute; width: 2px; left: 0; top: 3px; bottom: 3px; box-shadow: 0 0 10px rgba(0,0,0,0.2); } .pb-wrapper:after{ position: absolute; content: ''; background: rgba(192,227,232, 0.8) url(../images/scroll.png) no-repeat center center; width: 80px; height: 80px; top: 50%; left: 50%; margin: -75px 0 0 -35px; border-radius: 50%; z-index: 1000; }

Since we will be using Modernizr, we can define that on a touch device we should not be showing the circle.

We’ll add a hover effect which removes the circle for non-touch browsers:

.touch .pb-wrapper:after, .pb-wrapper:hover:after { display: none; }

The title will have the following style:

h3.pb-title { padding: 5px; font-family: 'Pacifico', Cambria, Georgia, serif; color: #374571; font-size: 14px; font-weight: 300; margin: 0; user-select: none; }

The scroll wrapper for the thumbnail list will have an extra padding and since its parent overflow is set to hidden, we won’t see the scrollbar:

.pb-scroll { position: relative; height: 100%; width: 150px; padding-right: 30px; overflow-y: scroll; overflow-x: hidden; box-sizing: content-box; }

The box-sizing is set to “border-box” in our normalize.css so we need to set it back to “content-box” in this case, because we really want the width to enlarge.

For touch devices, we’ll simply not add that padding. (Just thinking about optimization for the iPad, we know that the scrollbars won’t be shown.)

.touch .pb-scroll { padding-right: 0px; }

The photo strip list will have a transition for the opacity when we hover:

ul.pb-strip { padding: 0; list-style: none; position: relative; margin: 0 auto; width: inherit; opacity: 0.8; transition: all 0.3s ease-in-out; }

On hover, we’ll change the opacity and for touch devices we’ll reset it:

.pb-wrapper:hover ul.pb-strip, .touch .pb-wrapper ul.pb-strip{ opacity: 1; }

The list items will have a specified width and a little margin for the gap between the images:

ul.pb-strip li { display: block; width: 150px; position: relative; margin-bottom: 7px; }

The anchor will be set to display: block:

ul.pb-strip li a { display: block; }

In order not to repeat any content, we’ll simply use the title attribute to add a little tag on each thumbnail. This we will do with the pseudo-class :after. We’ll add a semi-transparent background and center it:

ul.pb-strip li a:after { position: absolute; z-index: 999; height: 20px; width: 120px; left: 10px; padding: 5px; bottom: 10px; background: rgba(255,255,255,0.6); content: attr(title); font-size: 13px; text-shadow: 0 1px 1px rgba(255,255,255,0.9); box-shadow: 1px 1px 2px rgba(0,0,0,0.2); }

Let’s add a subtle box shadow to the image since we will rotate the whole strip and we don’t want the edges to look too jagged in some browsers:

ul.pb-strip li img { display: block; box-shadow: 0 0 1px 1px #fff; }

Let’s define the positions of our four photo strips. We’ll separate them by 20% meaning that we’ll have them slightly overlapping for smaller screens and with a larger gap between each other for wider screens. Each photo strip will be slightly rotated in a different angle:

.pb-wrapper-1 { height: 89%; left: 20%; transform: rotate(3deg); } .pb-wrapper-2 { height: 85%; left: 40%; transform: rotate(-2deg); } .pb-wrapper-3 { height: 95%; left: 60%; transform: rotate(1deg); } .pb-wrapper-4 { height: 75%; left: 80%; }

We are using the Lightbox 2 script and we’ll adapt some style to fit our needs. First of all, let’s define that the default font should be inherited. We’ll also add a padding because we will move the navigation arrows outside the image. This will guarantee the space for the arrows:

#lightbox { font-family: inherit; padding: 0 85px; }

We need to set the overflow of the following container to visible because we want to set our navigation arrows outside. We’ll also add our paper background to the lightbox. The max-width of 100% will make the lightbox responsive. We’ll also need to set the height to auto. This will take away the resize effect of the lightbox but it’s a quick fix for our needs:

.lb-outerContainer { overflow: visible !important; background: #fff url(../images/paper.jpg) fixed repeat top left; border-radius: 0px; max-width: 100%; height: auto !important; }

We’ll take away the padding of the lb-container and add it instead to the image so that we don’t see anything in the transition moment (otherwise we would see a white 20px high container, because of our auto height):

.lb-container { padding: 0; } #lightbox img.lb-image { padding: 10px; max-width: 100%; }

Setting max-width: 100% to the image will also ensure that it fits into smaller viewports; it will resize if it exceeds the container width.

The navigation needs to be bigger, so that we set the arrows to the left and right outside of the lightbox image container:

.lb-nav { box-sizing: content-box; padding: 0 80px; left: -80px; }

Now we want to position the closing element absolutely. For that we set the parent to position: relative and position the element to our needs. We’ll also add a max-width of 100%, again, to be responsive:

.lb-dataContainer { position: relative; max-width: 100%; } .lb-data .lb-close { bottom: 10px; position: absolute; width: 73px; height: 73px; right: 5px; }

Let’s show those navigation arrows all the time; this will make our life easier when it comes to mobile devices. We’ll also position them absolutely and not float them like in the default style:

.lb-prev, .lb-next { position: absolute; cursor: pointer; width: 60px; height: 60px; top: 50%; margin-top: -30px; } .lb-prev, .lb-prev:hover{ background: url(../images/prev.png) no-repeat 50% 50%; } .lb-next, .lb-next:hover{ background: url(../images/next.png) no-repeat 50% 50%; }

The styling for the text elements is going to be the following:

.lb-data .lb-caption { font-family: 'Pacifico', Cambria, Georgia, serif; font-weight: 300; font-size: 30px; color: #fff; line-height: 32px; text-shadow: 1px 1px 1px rgba(0,0,0,0.6); } .lb-data .lb-number { text-indent: 4px; color: #c0e3e8; }

Last but not least: a tiny media query for small devices:

@media screen and (max-width: 650px) { div.pb-wrapper { position: relative; margin: 20px auto; height: 500px; left: auto; } } @media screen and (max-width: 350px) { #lightbox { padding: 0 20px; } .lb-nav { padding: 0; left: 0; } }

The fist media-query will set a fixed height for the strips and make them appear centered, under each other. The second one is for the lightbox style. We’ll put the navigation arrows on top of the image for smaller devices so that we have more space for the image.

And that’s it! I hope you liked this little experiment and find it useful and inspiring!