TUTORIAL

Creating a 'Two Step' Photograph Gallery using CSS only

Introduction

Following on from the success of my previous article 'Creating a Photograph Gallery using CSS only' I have now taken things a little further and produced a totally new method which does not require thumbnail images and has a unique two step method of display. The 'mouse hover' stage give a half size image and the 'mouse click' gives a full size image.

As with the previous article I hope to show you how to produce a professional quality photograph gallery using nothing more than an unordered list of photographs and a Cascading Style Sheet (CSS). I will take you through the styling one step at a time and end up converting:

Each step will again be thoroughly explained and have an example page showing the effect of the additional styling so that you can see what to expect.

This photograph gallery will also work in all the latest browsers and I have included hacks enabling Internet Explorer 5.5 to interpret the style correctly. The styling is not too long or difficult, but the layout does need a lot of attention to detail and pre planning.

Method

Step 1

The images

For this gallery I have used 24 images each 320px x 240px all on the theme of graffiti. I have chosen this size for several reasons:

  1. The file size for each image needs to be fairly small as all the images are required to be loaded before the gallery will work.
  2. As the 'thumbnails' surround the display area, on a 7 x 7 grid it is an easy calculation to find the thumbnail size is 64px x 48px.
  3. There will be five 'thumbnails' across the 320px horizontal display area (320px/5=64px)
  4. There will be five 'thumbnails' down the 240px vertical display area (240px/5=48px)
  5. There will be one 'thumbnail' in each corner making a total of 24 'thumbnails' (5+5+5+5+4=24)

It is always possible to adapt this layout to fit any quantity of images at any size but always consider the time required to download the images.

The basic (x)html list is given below.

<ul id="gallery">
  <li><img src="../images/g1.jpg" alt="#1" title="#1" /></li>
  <li><img src="../images/g2.jpg" alt="#2" title="#2" /></li>
  <li><img src="../images/g3.jpg" alt="#3" title="#3" /></li>
  <li><img src="../images/g4.jpg" alt="#4" title="#4" /></li>
  <li><img src="../images/g5.jpg" alt="#5" title="#5" /></li>
  <li><img src="../images/g6.jpg" alt="#6" title="#6" /></li>
  <li><img src="../images/g7.jpg" alt="#7" title="#7" /></li>
  <li><img src="../images/g8.jpg" alt="#8" title="#8" /></li>
  <li><img src="../images/g9.jpg" alt="#9" title="#9" /></li>
  <li><img src="../images/g10.jpg" alt="#10" title="#10" /></li>
  <li><img src="../images/g11.jpg" alt="#11" title="#11" /></li>
  <li><img src="../images/g12.jpg" alt="#12" title="#12" /></li>
  <li><img src="../images/g13.jpg" alt="#13" title="#13" /></li>
  <li><img src="../images/g14.jpg" alt="#14" title="#14" /></li>
  <li><img src="../images/g15.jpg" alt="#15" title="#15" /></li>
  <li><img src="../images/g16.jpg" alt="#16" title="#16" /></li>
  <li><img src="../images/g17.jpg" alt="#17" title="#17" /></li>
  <li><img src="../images/g18.jpg" alt="#18" title="#18" /></li>
  <li><img src="../images/g19.jpg" alt="#19" title="#19" /></li>
  <li><img src="../images/g20.jpg" alt="#20" title="#20" /></li>
  <li><img src="../images/g21.jpg" alt="#21" title="#21" /></li>
  <li><img src="../images/g22.jpg" alt="#22" title="#22" /></li>
  <li><img src="../images/g23.jpg" alt="#23" title="#23" /></li>
  <li><img src="../images/g24.jpg" alt="#24" title="#24" /></li>
</ul>

Step 2

The !DOCTYPE

Firstly and most importantly, make sure that you have the correct (X)HTML !DOCTYPE. Without this most browsers will be thrown into 'quirks' mode which will lead to all sorts of incompatibility problems. W3C QA - List of valid DTDs has a list of valid DOCTYPES that can be used. Select from XHTML1.0 or XHTML1.1 as these are more suitable for this styling. I use XHTML1.1 for all my current web pages.

Step 3

Adding links and style information

In order that I can use the :hover pseudo class style I need to change the basic unordered list into an unordered list of links. This is because Internet Explorer will only allow :hover to be used on links. I also need to add extra markup to target specific images.

The (x)html will now look like this.

<ul id="gallery">
  <li><a href="#nogo"><img src="../images/g1.jpg" alt="#1" title="#1" /></a></li>
  <li><a href="#nogo"><img src="../images/g2.jpg" alt="#2" title="#2" /></a></li>
  <li><a href="#nogo"><img src="../images/g3.jpg" alt="#3" title="#3" /></a></li>
  <li><a href="#nogo"><img src="../images/g4.jpg" alt="#4" title="#4" /></a></li>
  <li><a href="#nogo"><img src="../images/g5.jpg" alt="#5" title="#5" /></a></li>
  <li><a href="#nogo"><img src="../images/g6.jpg" alt="#6" title="#6" /></a></li>
  <li class="rgt"><a href="#nogo"><img src="../images/g7.jpg" alt="#7" title="#7" /></a></li>
  <li class="lft"><a href="#nogo"><img src="../images/g8.jpg" alt="#8" title="#8" /></a></li>
  <li class="rgt"><a href="#nogo"><img src="../images/g9.jpg" alt="#9" title="#9" /></a></li>
  <li class="lft"><a href="#nogo"><img src="../images/g10.jpg" alt="#10" title="#10" /></a></li>
  <li class="rgt"><a href="#nogo"><img src="../images/g11.jpg" alt="#11" title="#11" /></a></li>
  <li class="lft"><a href="#nogo"><img src="../images/g12.jpg" alt="#12" title="#12" /></a></li>
  <li class="rgt"><a href="#nogo"><img src="../images/g13.jpg" alt="#13" title="#13" /></a></li>
  <li class="lft"><a href="#nogo"><img src="../images/g14.jpg" alt="#14" title="#14" /></a></li>
  <li class="rgt"><a href="#nogo"><img src="../images/g15.jpg" alt="#15" title="#15" /></a></li>
  <li class="lft"><a href="#nogo"><img src="../images/g16.jpg" alt="#16" title="#16" /></a></li>
  <li class="rgt"><a href="#nogo"><img src="../images/g17.jpg" alt="#17" title="#17" /></a></li>
  <li class="pad"></li>
  <li class="lft"><a href="#nogo"><img src="../images/g18.jpg" alt="#18" title="#18" /></a></li>
  <li><a href="#nogo"><img src="../images/g19.jpg" alt="#19" title="#19" /></a></li>
  <li><a href="#nogo"><img src="../images/g20.jpg" alt="#20" title="#20" /></a></li>
  <li><a href="#nogo"><img src="../images/g21.jpg" alt="#21" title="#21" /></a></li>
  <li><a href="#nogo"><img src="../images/g22.jpg" alt="#22" title="#22" /></a></li>
  <li><a href="#nogo"><img src="../images/g23.jpg" alt="#23" title="#23" /></a></li>
  <li class="rgt"><a href="#nogo"><img src="../images/g24.jpg" alt="#24" title="#24" /></a></li>
</ul>

Make sure that each list item is on a single line as splitting them over several lines can cause unwanted spaces in Internet Explorer.

Style Ready List

Every list item is now enclosed in a link. Some have no class others have either 'lft' or 'rgt' which is short for 'left' and 'right'. I have also added an empty list item with a class="pad" to correct a bug in Internet Explorer, but more about that later.

I have used href="#nogo" instead of the more usual href="#" so that anyone clicking the link will not jump to the top of the page (just make sure you do not have an anchor #nogo on your page).

The (x)html unordered list is now complete and I will not need to make any more changes to it.

The Styling

Step 4

Removing the bullets

I will style the unordered list to removing the bullets and the indentation.

Browsers have different ways of doing this, Internet Explorer and Opera use margin values for the indentation whereas Mozilla/Netscape/Firefox all use padding values, so to cater for this I need to style the list as follows.

/* Removing the list bullets and indentation */
ul#gallery {
  padding:0; 
  margin:0; 
  width:448px; 
  height:336px; 
  position:relative;
  list-style-type:none;
  background:#888;
  }

Example Step 4

The bullet point are gone and the grey background of the <ul> is visible. In Internet Explorer the grey background will stretched in height to enclose all the images, whereas in other browsers the images will overflow the grey background.

Step 5

Resizing the images

The initial size of the images was calculated to be 64px x 48px to act as 'thumbnails' around the outside of the display area.

However, I have decided to have a 1px border around each image to act as a separator. To do this I will need to reduce the actual image size to 62px x 46px and the styling will be as follows:

/* Resize the images to 64px x 48px */
#gallery a img {
  position:relative;
  width:62px; 
  height:46px; 
  border:1px solid #888; 
  z-index:100;
  }

Example Step 5

The images are now reduced to 62px x 46px with the 1px border the same color as the background.

Step 6

Positioning the thumbnails

We now move on to positioning the thumbnail images around the edge of the display area.

To do this we will style the <li> tags.

Step 6a - moves the top line of thumbnails into place
/* Default style for list items */
#gallery li {
  width:64px; 
  height:48px; 
  float:left; 
  z-index:100;
  }

The images are now grouped in 4 rows with a blank space between image 17 and 18.

Example Step 6a

Step 6b - moves the 'lft' styled list items to the left hand edge
/* Styling the left side of the display area */
#gallery li.lft {
  float:left; 
  clear:left;
  }

A bit of a jumble, but the left side of the display area is now filled.

Internet Explorer will add a small space vertically between each image but that will be taken care of later.

Example Step 6b

Step 6c - moves the 'rgt' styled list items to the right hand edge
/* Styling the right side of the display area */
#gallery li.rgt {
  float:right; 
  clear:right;
  }

If you are using Internet Explorer you will see that the top, left and right images are in the correct place but the bottom row is not at the bottom. All other browsers have the images correctly positioned

Example Step 6c

This is where that extra list item (class="pad") is brought into play. We can style this to force the bottom row of images into place.

Step 6d - moves the bottom row of thumbnails into place in Internet Explorer
/* Force the bottom row of images into place (IE only) */
#gallery li.pad {
  height:0; 
  display:block; 
  margin-top:-2px; 
  width:448px; 
  font-size:0;
  }

The bottom row of images are now in place but we still have gaps between the horizontal row of images in Internet Explorer.

Example Step 6d

Step 6e - get rid of the gaps under the images in Internet Explorer
/* Getting rid of the image gaps */
#gallery a {
  position:relative; 
  width:64px; 
  height:48px; 
  display:block; 
  float:left; 
  z-index:100; 
  cursor:default;
  }

Example Step 6e

Step 7

Adding the :hover state

With all the thumbnails now in their correct position around the display area we can move on to styling the :hover stage of the thumbnails. Because the images are not actually thumbnails but a reduced size full images we can enlarge them to 160px x 120px and reposition them in the middle of the display area thus leaving a blank space where they were originally positioned. However if we did just this then we would lose our mouseover link and the selected image would flicker backwards and forwards between its original position and its new position.

In order to preserve our mouseover link we must expand the size of this link to be the full width and height of the <ul*gt;

We can do this by adding padding around the link to give a total height of 336px and a total width of 448px

What is more, the selected link must now drop behind all the other links in order that it does not obscure them and stop them being selected. So we must style the selected link with a z-index that is less than 100.

This section should be fully understood before continuing to the next stage.

/* Resizing the link on hover */
#gallery a:hover {
  width:160px; 
  height:120px; 
  padding:108px 144px; 
  position:absolute; 
  left:0; 
  top:0; 
  z-index:20;
  }

Example Step 7a

This example shows that you can hover over each thumbnail and make it jump to the display area and still remain hovering over the link. It also shows that you can move onto any other image and that too will jump to the display area.

We can now style the thumbnail image :hover to enlarge to 160px x 120px. I have chosen to lose the border in this resize.

/* Resizing the thumbnail on hover */
#gallery a:hover img {
  background:#eee; 
  position:relative; 
  width:160px; 
  height:120px; 
  border:0; 
  z-index:20;
  }

Example Step 7b

The hover image is now enlarged to half linear size and positioned centrally in the display area.

Step 8

Adding the :active and :focus states

Internet Explorer uses the :active pseudo class but all other browsers use to :focus pseudo class to style the mouse click.

As with the :hover style we will enlarge the image area, this time to 320px x 240px and reduce the padding to 48px at the top and bottom and 64px at each side thus maintaining a total size of 448px x 336px.

The clicked state of each link must also be moved further down the z-index so that it will be below the :hover stage. This will allow all links to be active and also allow the next :hover to appear on top of the 'clicked' image.

/* Resizing the link when 'clicked' */
#gallery a:active, #gallery a:focus {
  background:transparent; 
  width:320px; 
  height:240px; 
  padding:48px 64px; 
  position:absolute; 
  left:0; 
  top:0; 
  z-index:10;
  }

Example Step 8a

We can now style the 'clicked' image to be full size 320px x 240px.

/* Resizing the image when 'clicked' */
#gallery a:active img, #gallery a:focus img {
  background:#eee; 
  position:relative; 
  width:320px; 
  height:240px; 
  border:0; 
  z-index:10;
  }

Example Step 8b

Users of Internet Explorer may now notice a bug in this arrangement whereby the full sized clicked image does not display until the mouse is moved onto another image.

This is a very curious bug and I am not sure why it happens sometimes and not others. However, there is a very easy cure (hack) that can be applied without any problem to other browsers.

/* The 'click' hack for Internet Explorer */
a:visited {
  color:#000;
  }

Adding this global style to all links cures this problem. If anyone knows why, please contact me as I would be delighted to be enlightened.

Example Step 8c

Step 9

Adding a background image to the list

The photograph gallery is now taking shape, but we have a large blank display area and also blank spaces left by the images as the get enlarged.

It is possible to fill these gaps with an overall background image for the <ul>.

For my example I have created an image that is in keeping with the graffiti theme and also give an instruction to click the vacant space left by the hover stage.

background image

You can of course style this as you like.

Modify the following line in the existing ul#gallery style to add the background image.

/* Adding the background image */
ul#gallery {
  padding:0; 
  margin:0; 
  width:448px; 
  height:336px; 
  position:relative; 
  background:#888 url(../image/g26.jpg);
  }

Example Step 9

We now have the central default image in place and when you hover over any image it gets replaced by an instruction to 'click' which will produce the full sized image.

Step 10

Opera doesn't like :focus or :active

'Tis true. Opera doesn't work with :active and doesn't hold the :focus state when the mouse button is clicked and released.

We can just let Opera do it's own thing or we can apply a hack that tells Opera to just use the :hover as a full size image and ignore the two steps.

Yes there is a hack that targets Opera only, it is 'valid' css but the w3c validator does not recognise it as it is only a recommendation.

/* hack for Opera 7+ */
@media all and (min-width:0px){
#gallery a:hover {
  background:#888; 
  width:320px; 
  height:240px; 
  padding:48px 64px; 
  position:absolute; 
  left:0; 
  top:0; 
  z-index:10;
  }
#gallery a:hover img {
  background:#aaa; 
  position:relative; 
  width:320px; 
  height:240px; 
  border:0; 
  z-index:10;
  }
}

ONLY Opera 7+ understands this conditional styling which just enlarges the hover link and image to 320px x 240px (the same size as the active / focus link and image).

Example Step 10

If you are using Opera 7+ then you will now see a full size image on hover, with the instruction to 'click' covered up by a grey background. The central default image is still in place and if you should click an image then you will not notice the problem.

Conclusion

Feel free to use this styling 'as is' with your own images or adapt it to use images of a different size or even a different arrangement. The only limitation is your imagination.

Oh, and a big thank you to the photographers who supply their work 'free of charge' to the stock.xchng