Create An Image Gallery With CSS3 3D Transforms
Jun 23, 2012 | In CSS, jQuery, Tutorials |CSS3 offers many exciting new opportunities for web designers looking to spice up their webpages, but one of the most interesting ones are the 3D transforms. Objects on the page can be manipulated in 3D space. In this tutorial, we’ll make an image gallery that utilizes 3D transforms to make things a bit more interesting.
HTML
The first thing we need is an element that will act as a container for the images.
<section id="images"> </section>
Now, we need to create the markup for each image.
<div class="image" title="This is random nonsense, this is random nonsense."> <img src="images/1.jpeg"> </div>
There’s a div with a class of “image”, along with a title. This title will be what’s contained in the caption on the back of the image. Inside the div, we have the actual image displayed.
Repeat this structure for 8 more images.
<section id="images"> <div class="image" title="This is random nonsense, this is random nonsense."> <img src="images/1.jpeg"> </div> <div class="image" title="This is random nonsense, this is random nonsense."> <img src="images/2.jpeg"> </div> <div class="image" title="This is random nonsense, this is random nonsense."> <img src="images/3.jpeg"> </div> <div class="image" title="This is random nonsense, this is random nonsense."> <img src="images/4.jpeg"> </div> <div class="image" title="This is random nonsense, this is random nonsense."> <img src="images/5.jpeg"> </div> <div class="image" title="This is random nonsense, this is random nonsense."> <img src="images/6.jpeg"> </div> <div class="image" title="This is random nonsense, this is random nonsense."> <img src="images/7.jpeg"> </div> <div class="image" title="This is random nonsense, this is random nonsense."> <img src="images/8.jpeg"> </div> <div class="image" title="This is random nonsense, this is random nonsense."> <img src="images/9.jpeg"> </div> </section>
That’s all the HTML that’s necessary.
CSS
We’ll start off with some simple styling to make the page look nice. Right now, there’s just a bunch of images stacked vertically on the page. As far as layouts go, it’s not too bad. I’ve seen worse. But in this case, let’s make it a bit easier on the eyes.
body { background: #eee; } #images { width: 450px; height: 450px; margin: 100px auto 0 auto; -webkit-box-shadow: 0px 0px 20px 5px #888; }
A box with a drop shadow on a grey background. Much better. Unfortunately, the images aren’t completely inside it yet.
.image { width: 150px; height: 150px; float: left; }
This looks nice, but there’s still a few things that need to be added.
.image { width: 150px; height: 150px; float: left; opacity: 0.9; -webkit-transition: all 300ms ease; } .image:hover { cursor: pointer; opacity: 1; }
That’s all the styles we need for now.
Remember the “title” attribute that each “image” div has? We need a way to put that on the back of each image, and this is where CSS3 psuedo-elements come in. Basically, with only CSS, it is possible to create another element right next to each “image” div we have on the page.
.image:after { content: attr(title); }
Now, right after each “image” will be an element with the contents of the “title” attribute inside. However, we also need to position this on the back of each image, and for that we will use CSS3 3D transforms. Before they can be used, the following code needs to be added to the parent element of whatever we’re going to manipulate.
-webkit-perspective: 1000;
Defining perspective is necessary for 3D elements to have… perspective, surprisingly enough. WSC does an excellent job of explaining this.
Without perspective, the elements would look boring and flat when rotating.
#images { -webkit-perspective: 1000; width: 450px; height: 450px; margin: 100px auto 0 auto; background: #888; -webkit-box-shadow: 0px 0px 20px 5px #888; }
Now the “#images” section is properly set up.
You’ll notice that the “:after” part of each “image” still isn’t in the right spot. Let’s fix this.
.image:after { content: attr(title); display: block; width: 138px; height: 138px; padding: 5px; background: #eee; border: 1px solid #999; -webkit-transform: rotateY(180deg) translateY(-153px); }
Right now, all the pseudo-elements are behind the images – but we can still see them. Paste this code into the “.image:after” part:
-webkit-backface-visibility: hidden;
This makes the backface of it invisible, which allows us to stick it to the back of another element without showing through.
Also, the text looks boring.
font-family: arial; font-size: 16px; line-height: 24px; color: #333;
Better.
So far, for the “.image:after”, you should have the following code.
.image:after { content: attr(title); display: block; width: 138px; height: 138px; padding: 5px; background: #eee; border: 1px solid #999; -webkit-transform: rotateY(180deg) translateY(-153px); -webkit-backface-visibility: hidden; font-family: arial; font-size: 16px; line-height: 24px; color: #333; }
Javascript
What do we want to happen when we click on an image? For the image to flip over and reveal the caption underneath. There are several ways to do this, but let’s just use some javascript.
Before we begin, include the jquery library in your code.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
Now, let’s start.
$(document).ready(function(){ });
This part is necessary so that the code inside only executes when all the elements on the page are fully loaded.
Let’s think this through; we want something to happen when an image is clicked.
$('.image').click(function(){ });
We want it to switch back and forth between being rotated 180 degrees around the Y axis and being rotated 0 degrees around the Y axis. For this, we’ll use the HTML5 “data-” attributes capability. Part of HTML5 is that it is now perfectly acceptable to define a custom attribute beginning with “data-”, such as “data-flipped”, which is what we’ll use. In here, we’ll store whether or not that particular element is flipped.
$('.image').click(function(){ var flipped = $(this).attr('data-flipped'); });
We can now use this to check if the element is flipped or not.
if(flipped=='yes'){ $(this).attr('data-flipped','no'); } else { $(this).attr('data-flipped','yes'); }
If it isn’t flipped, it is after being clicked. If it was, now it isn’t. Simple. However, this doesn’t actually make the thing flip. Let’s fix that.
if(flipped=='yes'){ $(this).attr('data-flipped','no'); $(this).attr('style','-webkit-transform: rotateY(0deg);'); } else { $(this).attr('data-flipped','yes'); $(this).attr('style','-webkit-transform: rotateY(-180deg);'); }
Done. Here’s all the code you should have:
$(document).ready(function(){ $('.image').click(function(){ var flipped = $(this).attr('data-flipped'); if(flipped=='yes'){ $(this).attr('data-flipped','no'); $(this).attr('style','-webkit-transform: rotateY(0deg);'); } else { $(this).attr('data-flipped','yes'); $(this).attr('style','-webkit-transform: rotateY(-180deg);'); } }); });
At this point, you should have a working image gallery with flipping images and captions. I hope you enjoyed creating this, and that you learned something today. As always, the comment section is below if you have any questions or… well, comments.