From our sponsor: Meco is a distraction-free space for reading and discovering newsletters, separate from the inbox.
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.
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.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
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!
Awesome as always! Thanks
Mary Lou where do you find these genius ideas ?
Great, once again.
Thanks
Nice! I can see this easily being used in a portfolio!
Awesome!! I love Codrops!
Great idea, very nice !
finally something AWESOME and USEABLE from codrops !!!!
love the idea of this the photo strip is a cool idea on its own, never mind the lightbox with nice arrows and buttons 🙂
love this site so much inspiration!!
Now, THAT I call directional nav !
J’adore.
Merci
So pretty <3
Will definitely be trying this out at some point!
Would it be possible to use the same concept but make the strip be horizontal and be responsive horizontally, accordingly? Love your tuts, you are one of the best designers and front-end devs I have seen, you pay so much detail to presentation, it’s great 🙂 thanks
Original j’aime 🙂
Thank you all very much for your wonderful feedback!
@Roma, maybe Elastislide could be interesting to you: http://tympanus.net/codrops/2011/09/12/elastislide-responsive-carousel/
It’s not the same, it’s a carousel, but maybe it helps…
Cheers,
ML
In the words of a shocked man from the west coast USA in utter awe of sheer genius: “BADASS”.
Hi Mary Lou,
It really looks great. Just to test browser compatibility, I checked it with IE9 and with IE, there is empty lightbox screen at the top but not active with the transparent black background. Just seems like trying to load an image with all elements like loader, close and right left buttons… Except this bug, it is working properly with IE9. Is it fixable?
Hi hoko, thanks a lot for your feedback! It was a conflict with our advertising widget and it’s fixed now 🙂
The version in the ZIP file does not have that widget and it should work fine.
Thanks again,
cheers,
ML
very cool looking design
Love it so much
Thank you so much
Awesome!! great idea : D \m/
awesome.
Awesome!!!
In safari there is a small detail: The scroll bar appears next to lightbox.
amazing…ty (^_^)
Too cool! I wonder if it will work on top of Animated Responsive Image Grid.
Thank you very much for sharing these, really brilliant think….
Yet another great work from codrops 🙂
is it possible to add another button by the close button? if i wanted to add a buy it now link for the portfolio?
anyone know if that is possible to add another button next to the close button so i can link it to a buy it now for an object for sale in a portfolio?
Neat. Scrolling in mobile could be improved with the addition of
-webkit-overflow-scrolling: touch;
(iOS5)woa this is so cool 😀