I needed to make a single page “house-for-sale” announcement on the web. I did not want to take the use of the commercial reap-estate sites where all that is automatized but make a simple, but elegant page with modern web standards. My web design information was dating from the days where elements were actually table cells. I decided that there was a need for a modern, CSS  Layer based design. I wanted also to take the use of layered techniques to propose a small photo-album that would look a little bit like it would have been created with Flash. Below I will explain how the photo-album was created. Should you want to take a look at the final output already, check the French and English versions of my sales leaflet.

In the final design, we have a left column that contains the photo-album. I have created two sets photos. Only five photos were selected to make the thumbnails to fit using a reasonable size. Another reason is to maintain a reasonable downloading time. The CSS method used below make all the photos be downloaded automatically so that the thumbnail photo clicking makes the actual photo and its caption to change without any delay. The user experience is very Flash-like.

All images were GIMP’ed (and not Photoshopped because I am against piracy) to a fixed size. Again, we are looking for a reasonable download speed and GIMP is a good tool to make small, interlace-enabled PNG-pictures.  A fixed size is good to avoid hassle with the image transparency and/or background showing in a wrong place when we switch between pictures. Of course, this process is entirely manual, as everything else in this project.

Let’s do some coding: First we will create picture, caption and thumbnail placeholders.

<div id="pictures" style="position: relative; width: 325px; height: 250px;
                          z-index: 2; margin-top: 10px; margin-left: auto; margin-right: auto;">
<div id="picture0" style="position: absolute; width: 32px; height: 32px; z-index: 8;
                               background-image: url('images/ajax-loader.gif');
							   background-repeat: no-repeat;
                               position: absolute; left: 160px; top: 115px; visibility: visible;"></div>
<div id="picture1" style="position: absolute; width: 325px; height: 250px; z-index: 7;
                               background-image: url('images/main325x250en.png');
							   background-repeat: no-repeat;
                               position: absolute; left: 0px; top: 0px; visibility: hidden;"></div>
<div id="picture2" style="position: absolute; width: 325px; height: 250px; z-index: 6;
                               background-image: url('images/picture2-325x250.png');
							   background-repeat: no-repeat;
                               position: absolute; left: 0px; top: 0px; visibility: hidden;"></div>
<div id="picture3" style="position: absolute; width: 325px; height: 250px; z-index: 5;
                               background-image: url('images/picture3-325x250.png');
							   background-repeat: no-repeat;
                               position: absolute; top: 0px; left: 0px; visibility: hidden;"></div>
<div id="picture4" style="position: absolute; width: 325px; height: 250px; z-index: 4;
                               background-image: url('images/picture4-325x250.png');
							   background-repeat: no-repeat;
                               position: absolute; left: 0px; top: 0px; visibility: hidden;"></div>
<div id="picture5" style="position: absolute; width: 325px; height: 250px; z-index: 3;
                               background-image: url('images/picture5-325x250.png');
							   background-repeat: no-repeat;
                               position: absolute; left: 0px; top: 0px; visibility: hidden;"></div>
</div>
<div id="captions" style="position: relative; width: 325px; z-index: 2; margin-left: auto;
                          margin-right: auto; margin-top: 5px; height: 50px;">
<div id="caption0" style="position: absolute; width: 325px; height: 50px; z-index: 8;
	                           left: 0px; top: 0px; visibility: visible;"></div>
<div id="caption1" class="caption" style="position: absolute; width: 325px; height: 50px;
	                                            z-index: 7;left: 0px; top: 0px; visibility: hidden;">
				Pellentesque eu lacus at dui mattis tincidunt.</div>
<div id="caption2" class="caption" style="position: absolute; width: 325px; height: 50px;
	                                            z-index: 6;left: 0px; top: 0px; visibility: hidden;">
				<span class="captionPurple">Vivamus !</span> ullamcorper, ante eget vulputate auctor,
				mi pede volutpat velit, sit amet ultricies nibh diam non libero.</div>
<div id="caption3" class="caption" style="position: absolute; width: 325px; height: 50px;
	                                            z-index: 5;left: 0px; top: 0; visibility: hidden;">
				Nulla facilisi. Morbi quam tortor, laoreet in, bibendum nec, tincidunt quis, nulla.</div>
<div id="caption4" class="caption" style="position: absolute; width: 325px; height: 50px;
	                                            z-index: 4;left: 0px; top: 0; visibility: hidden;">
				Curabitur ut libero ac justo varius facilisis. Nulla facilisi. Sed id justo.</div>
<div id="caption5" class="caption" style="position: absolute; width: 325px; height: 50px;
	                                            z-index: 3;left: 0px; top: 0; visibility: hidden;">
				Donec placerat sodales libero. Mauris sollicitudin felis vitae enim semper mattis.</div>
</div>
<div id="thumbnails" style="position: relative; width: 325px; height: 61px; z-index: 2;
                            margin-left: auto; margin-right: auto;
							margin-top: 5px; margin-bottom: 15px;">
<div id="thumb1" onclick="javascript:changePicture(1);"
	                  style="position: relative; width: 61px; height: 61px; z-index: 7; float: left;
					  background-image: url('images/main61x61.png'); background-repeat: no-repeat;"></div>
<div id="thumb2" onclick="javascript:changePicture(2);"
	                  style="position: relative; width: 61px; height: 61px; z-index: 6; float: left;
					  margin-left: 5px; background-image: url('images/picture2-61x16.png');
					  background-repeat: no-repeat;"></div>
<div id="thumb3" onclick="javascript:changePicture(3);"
	                  style="position: relative; width: 61px; height: 61px; z-index: 5; float: left;
					  margin-left: 5px; background-image: url('images/picture3-61x61.png');
					  background-repeat: no-repeat;"></div>
<div id="thumb4" onclick="javascript:changePicture(4);"
	                  style="position: relative; width: 61px; height: 61px; z-index: 4; float: left;
					  margin-left: 5px; background-image: url('images/picture4-61x61.png');
					  background-repeat: no-repeat;"></div>
<div id="thumb5" onclick="javascript:changePicture(5);"
	                  style="position: relative; width: 61px; height: 61px; z-index: 3; float: left;
					  margin-left: 5px; background-image: url('images/picture5-61x61.png');
					  background-repeat: no-repeat;"></div>
</div>

Still with me? Great! If you look at the layers carefully, you would notice that there are caption and picture layers that are numbered as “zero“. They are used during the initial opening of the page, to give the annoying Flash-like impression of “loading..” – pictures! Probably because of the slow server of my ISP, the initial loading of some ten pictures can take something like five to ten seconds. A long time to keep a potential customer waiting. At least I can give the client a message that I am working hard to show the pictures, while the actual body text is visible quite quickly on most browsers.
Not quite Flash or Ajax, actually an animated GIF
This is done by selecting the picture0 and caption0 layers visible when the page loads. In picture0 layer we will show the infamous ever-rotating bars to keep the potential client hypnotized with what is only an animated GIF, nothing to do with Flash.

All the pictures and thumbnails are defined as background images of other layers. They will be loaded automatically on the background when the page loads. We need to switch from the picture0/caption0 pair to picture1/caption1 layer pair once pictures have been all loaded.

Can we get information when they are loaded? No, at least not easily. You may want to try to experiment with each browser’s Document Object Model (DOM), but luckily IE7, Firefox 3 and Chrome all seem to work in predicable manner with the delayed JavaScript execution method that I will present next:

<script type="text/javascript">
//<![CDATA[
var pictures = null;
var captions = null;
var timerId = null;

function init ( ) {
	visiblePicture = 1;
	pictures = new Array();
	pictures[0] = document.getElementById('picture0');
	pictures[1] = document.getElementById('picture1');
	pictures[2] = document.getElementById('picture2');
	pictures[3] = document.getElementById('picture3');
	pictures[4] = document.getElementById('picture4');
	pictures[5] = document.getElementById('picture5');
	captions = new Array();
	captions[0] = document.getElementById('caption0');
	captions[1] = document.getElementById('caption1');
	captions[2] = document.getElementById('caption2');
	captions[3] = document.getElementById('caption3');
	captions[4] = document.getElementById('caption4');
	captions[5] = document.getElementById('caption5');
	timerId = setTimeout( "loadWait()", 100);
	return;
}

function changePicture ( pictureNo ) {
	for ( var i = 0; i <= 5; i++ ) {
		pictures[i].style.visibility = 'hidden';
		captions[i].style.visibility = 'hidden';
		if ( i == pictureNo ) {
			pictures[i].style.visibility = 'visible';
			captions[i].style.visibility = 'visible';
		}
	}
	return;
}

function loadWait ( ) {
	changePicture ( 1 );
}
//]]>
</script>

<body onload="javascript:init();">

The init() function fires a one-second delay timed call-back function, which has the job to turn the picture1/caption1 layer pair visible. The delay is not important, in practice the loadWait() function will not get in execution before the browser has parsed all the <div> layers (and their background images). Therefore this is a great method – although not at all determistic – to show the images in a synchronized manner, once they have been all downloaded. User experience is very satisfying ! (And if you think otherwise, please give me some feedback by commenting this post).