News

Use CSS3 to create an image preview grid

Using Google images as inspiration you can create an engaging image preview to allow users to view pictures more clearly

previewgrid

CSS3 has come a long way since it was first introduced and there are so many features that can help you to achieve great things – and there’s still plenty more to look forward to. Not so long ago, it felt like we were hiding behind the lack of cross-browser compatibility to avoid learning new techniques – techniques that would actually dramatically improve our workflow and enhance our webpages.

Not anymore, as CSS animations are finally available in all major browsers, even in Internet Explorer (since version 10), so now we don’t need to hide behind anything anymore. We can achieve many things just through using CSS.

So what we’re going to do in this tutorial is use the Google images results page as inspiration and create an expanding image preview grid that will also be responsive. The expanding image preview grid can be used for anything you like, but for our purposes we’ll assume this is for advertising a pixel-art game to potential new users. The idea here is that when you click on the images, you will be presented with more information about the game underneath. So, let’s get started!

Get ahead

The first step is to create a new HTML5 file and then add the meta information within the head section. What we need to make sure of is that we have the ‘viewport’ meta tag included for when we make this responsive, as well as the IE conditional for the HTML5 shiv. Lastly we’re going to add in a Modernizr file.

001    <head>
002    <meta charset=”UTF-8” />
003    <meta http-equiv=”X-UA-Compatible”
content=”IE=edge,chrome=1”> 
004    <meta name=”viewport” 
content=”width=device-width, initial-scale=1.0”>
005     <!--[if IE]>
006       <script src=”http://html5shiv.googlecode.com/svn/trunk/html5.js”> </script>
007     <![endif]-->
008    <title>Grid Thumbnails</title>
009    <link rel=”stylesheet” type=”text/css” 
href=”css/main.css” />
010    <script src=”js/modernizr.custom.js”>
</script>
011    </head>

Section grid

In this step, we’re going to start adding in some HTML for our product’s content. In between the ‘body’ tag we’re going to add a ‘section’ element that will be used as a wrapper and then within that we will create an ‘article’ element. We then give our article element an ID name of ‘01’ and this will, of course, be our first product.

001    <section>  
002      <article id=”01”>
003      </article>
004    </section>

Expand the HTML

Now that we have the article element added, let’s go ahead and add some more HTML that will allow us to add in the necessary content. The first bit of content will be our images. Within the anchor element we’ll add a target ID of ‘#01’ so when we click the image, the browser will move up accordingly. Everything else is straightforward.

001    <section>  
002      <article id=”01”>
003          <a href=”#01”><img src=”images/                    cover01.jpg” /></a>
004            <div class=”info”>
005             <div class=”description”>
006             <h1></h1>
007             <p></p>
008             </div>
009          </div>
010      </article>
011    </section>

List and more button

We have almost finished our skeleton HTML for our first product, and all we need to do now is add in an unordered list and another anchor tag for a ‘learn more’ button that we will position at the bottom of our product description. We give this button a class name of ‘moreBtn’ and in the next step we will add in all the content that is needed.

001      <a href=”#01”><img src=”images/cover01.jpg” /></a>
002            <div class=”info”>
003             <div class=”description”>
004             <h1></h1>
005             <p></p>
006              </div>
007                <ul>
008                  <li></li>
009                  <li></li>
010                  <li></li>             
011                </ul>
012            <a class=”moreBtn” href=”#”></a>
013          </div>

The image content

Let’s finish up our HTML by adding in the content to the markup we added in the last few steps. Firstly we need to give our product description a title. As this will be our first product, it would make sense to call this ‘Product #01’. Then, using some dummy text (Lorem Ipsum), we can populate the rest of our product description. Now copy and paste this HTML 15 times or more.

001    <article id=”01”>
002      <a href=”#01”><img src=”images/cover01.jpg” /></a>
003         <div class=”info”>
004           <div class=”description”>
005             <h1>Product #1</h1>
006             <p>Lorem ipsum dolor sit 
amet, consectetur adipiscing elit. In 
in massa ultrices diam lobortis convallis 
quis in risus. Phasellus a augue vitae 
sapien condimentum condimentum quis at 
eros. In nisl lacus, pharetra nec commodo 
quis, accumsan ac sapien.</p>
007             </div>
008              <ul>
009                <li>Lorem ipsum dolor</li>
010                <li>Consectetur adipiscing</li>
011                <li>Fringilla libero</li>
012              </ul>
013            <a class=”moreBtn” href=”#”>
learn more</a>
014         </div>
015      </article>

Article white space

When using the ‘article’ element, we must ensure that we leave no whitespace in between the last closing article element and the next open one. This is because we will be changing the layout of these elements using ‘display: inline-block’ and whitespace will cause a 4px gap in between each element when the page is rendered. Also, make sure when you’ve copied and pasted each article element, you change the article ID and anchor target ID.

001    </div>
002     </article><article id=”02”>
003    <a href=”#02”><img src=”images/cover01.jpg” /></a>

The CSS reset

Now create a new CSS file, call it ‘styles.css’ and save it within a new folder called ‘CSS’. Then at the very top we are going to add in a CSS reset. The most popular one is Eric Meyer’s, which you can find at meyerweb.com/eric/tools/css/reset but the one thing you’ll want to add to this is the ‘box-sizing’ reset.

001    *, *:after, *:before { 
002        -webkit-box-sizing: border-box; 
003        -moz-box-sizing: border-box; 
004        box-sizing: border-box; 
005    }

The body section

Firstly we give our body some default styling and then the section element will be used as a container. We want the maximum width to be no more than a 1,000px wide. This will allow us to have enough room to fit at least three images across the screen. We then centre the grid using ‘margin: 0 auto’ and just in case we need to position anything absolutely, we can set its position to ‘relative’.

001    body {
002        font-family: Arial, sans-serif;
003        color: #aaaeb2;
004        background: #f1f1f1;
005    }
006    section {
007          max-width: 1000px;
008          margin: 0 auto;
009          position: relative;
010        }
011        

Section article

We’re going to set the product images to ‘inline-block’, which will force them to sit side by side but also act as blocks, so we can specify their width and height properties. We then make sure they are vertically aligned to the top of their row and give them a 50 per cent width to help make these more responsive for when we finally add the media queries to our CSS.

001     section article {
002          vertical-align: top;
003          display: inline-block;
004          width: 50%;
005          margin-bottom: -4px;
006        }
007        

Style the content images

Each image will be set to 100 per cent of its containing element, which will be our ‘article’ element. The height will be based on its width to maintain its aspect ratio. Lastly we will give it a 4px padding all around to allow us some breathing space in between each image.

001     section img {
002          width: 100%;
003          height: auto;
004          padding: 4px;
005        }

Style the information

The information that will be shown underneath our product images after we have clicked the image will be set to 150 per cent wide and hidden. We will also add some padding and margin to give the content some breathing space and then float it to the left.

001      section .info {
002          width: 150%;
003          padding: 3em 0;
004          margin: 0 10%;
005          position: relative;
006          float: left;
007          opacity: 0;
008          height: 0;
009          font-size: 0;
010        }

Product content styles

Let’s now add some styles to our product information. Firstly we’ll make sure we use ‘em’ values here so everything can become scalable for when we make this responsive. We will give our product title some bottom margin and then combine the ‘p’ and ‘ul’ elements to the same rule and give them some bottom margin and then set the ‘line-height’ to 140 per cent.

001     section .info h1 {
002          margin-bottom: .5em;
003        }
004        section .info p,
005        section .info ul {
006          margin-bottom: 2em;
007          line-height: 140%;
008        }

List styles

Now let’s target our unordered list and give it some left margin that will be a fixed value using pixels. The list items will then be given square bullet points instead of the default circles. This is personal preference, so you may want to leave it as the default. The last thing we’re doing is applying a line height of 140 per cent to each list item.

001    section .info ul {
002          margin-left: 20px;
003        }
004        section .info li {
005          list-style: square;
006          line-height: 140%;
007        }

Learn more button

The ‘Learn more’ button will be placed at the very bottom of our product information and we will make sure that it has some breathing space by giving it a little margin and padding. The button will be blue with white text and we will also give it a nice transition into a lighter blue for when users hover over it.

001      section .info .moreBtn {
002          display: block;
003          margin-top: .4em;
004          padding: .4em;
005          background: #006699;
006          text-align: center;
007          font-size: 1.1em;
008          color: white;
009          text-decoration: none;
010          text-transform: uppercase;
011          transition: 0.3s background-color;
012    }
013    section .info .moreBtn:hover {
014          background: #0672a8;
015        }

nth-child selectors

In this step, we will use ‘:nth-child()’ selector to select the first ‘.info’ of every two and the second ‘.info’ of every two. The first ‘.info’ can remain where it is, but the second should be moved to the left by adding a negative value of -100 per cent, which will make it appear in the same position as the first.

001    article:nth-child(2n+1) .info {
002          left: 0;
003        }
004        article:nth-child(2n+2) .info {
005          left: -100%;
006        }

Reveal the info

In this step, we’re going to add in a rule that will allow us to reveal the product’s information. Firstly we will set its height to ‘auto’ so it will change from ‘0’ to whatever value is required to contain all of its content. The font size will also go from ‘0’ to 100 per cent and then we’ll set the opacity to ‘1’ to reveal our content. Finally we give it some animation by using ‘transition’.

001     section article:target .info {
002          height: auto;
003          font-size: 100%;
004          opacity: 1;
005          transition: .4s .4s opacity;
006        }

Image identifier

To make it obvious which product image the user is looking at, we can add a nice subtle drop shadow to the bottom of our image. So, when we click on that image, using the ‘target’ pseudo-selector (as we did in the previous step) we can make sure the drop shadow is added to that clicked image. Let’s polish it off by adding some animation to the shadow.

001    section article:target img {
002          box-shadow: 0 8px 3px -4px 
rgba(0,0,0,.5);
003          transform: scale(1.1);
004          transition: .5s;
005        }

Info elements

Now because there are three products per row, the ‘.info’ elements need adjusting again so they always start on the screen’s far left. Here we’ve moved the second of three products 100 per cent to the left and the third 200 per cent to the left. It’s important to use percentages here for our page to be responsive.

001    section article:nth-child(3n+1) .info {
002          left: 0;
003        }
004        section article:nth-child(3n+2) .info {
005          left: -100%;
006        }
007        section article:nth-child(3n+3) .info {
008          left: -200%;
009        

Finish the more button

We have already added some styles to the ‘Learn more’ button in an earlier step, but let’s add some more to help with how we position it and to resize it. To achieve this we will give it a display value of ‘inline-block’ and float it left. We’re going to clear the float and then specify its width as ‘auto’. Lastly we will use margin-top to give us some space.

001        section article .moreBtn {
002          display: inline-block;
003          float: left;
004          clear: both;
005          width: auto;
006          margin-top: 2em 0 0 0;
007        }
008        

Position the content

One of the last steps to complete is positioning our product content properly using the ‘float’ and ‘width’ properties. As we have mentioned before, we want this to be responsive, so we will need to use percentages here. The description will be 50 per cent of the width of the article element and the unordered list will be 30 per cent. This will give us lots of white space.

001      section article .description {
002          float: left;
003          width: 50%;
004        }
005        section article ul {
006          float: right;
007          width: 30%;
008        }

Media queries

To make our project fully responsive, we need to add some media queries with a minimum width of 400px. When the browser window reaches a minimum width of 400px, each product will then be made 30 per cent wide and the product information will be made 280 per cent wide. This will also cause the grid to become a row of three instead of two.

001       @media only screen and (min-width: 400px) {
002          section article {
003            width: 33%;
004          }
005          section article .info {
006            width: 280%;
007          }
008        }
009



Final thoughts

Now we can resize our page and be happy that our page renders well in different-sized browser windows. As you can see, using CSS3 for things like image grids can be very easy to achieve and also very effective. As a web designer, you have to ask yourself whether or not you really need to use jQuery all the time for animated elements. This tutorial has aimed to show you otherwise – so have fun creating yours!

×