Flexible thumbnails v4

Introduction

This page describes how to get a bunch of thumbnails to flow with the browser width. To make it all more interesting, a frame with a shadow is added and the background is a gradient.

The method is XHTML 1.0 Strict compliant and has been tested with Internet Explorer 6 SP1, Opera 6.05, Opera 7.51, Phoenix 0.4 and Firefox 1.0 under Windows XP and Safari 1.2.4 under OSX.

Sample

[Snail]

[867x650 pixels] [2592x1944 pixels]

[Bumblebee]

[867x650 pixels] [2592x1944 pixels]

[Butterfly]

[488x650 pixels] [1944x2592 pixels]

[Ant and finger]

[867x650 pixels] [2592x1944 pixels]

[Fungus]

[488x650 pixels] [1944x2592 pixels]

[Caterpillar]

[867x650 pixels] [2592x1944 pixels]

To the point

Let's start with the XHTML and the CSS and explain the meaning of it all later on. indicates that the line should not break.

XHTML

<div class="thumbLandscape">
  <p class="thumbImage">
    <a href="pic/bi_20040624_1653_Draebersnegl.jpg"><img
    src="pic/tn_20040624_1653_Draebersnegl.jpg"
    width="240" height="180" alt="[Snail]" /></a>
  </p>
  <p class="thumbCaption">
    [<a href="pic/bi_20040624_1653_Draebersnegl.jpg">867x650 pixels</a>]
    [<a href="pic/20040624_1653_Draebersnegl.jpg">2592x1944 pixels</a>]
  </p>
</div>

CSS

/* General */
body {
  background: #FC9 url(WarmGradient.png) repeat-x fixed bottom;
}
div.thumbPortrait, div.thumbLandscape {
	float: left;
	width: 240px;
	margin-right: 10px;
}

/* Everything but IE */
body>div.thumbLandscape {
	background: url(Frame240x180_S.png) transparent no-repeat;
	padding: 77px 17px 1em 17px;
}
body>div.thumbPortrait {
	background: url(Frame180x240_S.png) transparent no-repeat;
	padding: 17px 17px 1em 17px;
}

/* IE only, thanks to the star bug
http://www.info.com.ph/~etan/w3pantheon/style/starhtmlbug.html */
* html p.thumbImage a {
	display: block;
	cursor: pointer;
}
* html div.thumbLandscape p.thumbImage a {
	padding: 77px 77px 1em 17px;
	height: 240px;
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=
'files/Frame240x180_S.png',sizingMethod='crop');
}
* html div.thumbPortrait p.thumbImage a {
	padding: 17px 17px 1em 17px;
	height: 185px;
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=
'Frame180x240_S.png',sizingMethod='crop');
}

* html div.thumbLandscape, * html div.thumbPortrait {
	width: 274px;
}
* html p.thumbImage {
	position: absolute;
}
* html p.thumbCaption {
	padding: 220px 15px 0px 15px;
}

How does it work?

Principle

All images are placed in floating blocks, which uses the frame graphic for background. Simple. If it wasn't for Internet Explorer 6.0 and its lack of direct support for transparent PNGs, this page would not exist. But Internet Explorer 6.0 is still alive, so we hack it.

Internet Explorer has a proprietary extension to CSS called filter. We use a filter named AlphaImageLoader which allows for transparency. Unfortunately this filter introduces another problem: Visually it works well, but interactively it takes all actions from the elements the block contains. This means that links won't work anymore. Time for more hacking.

Graphic

The gradient is just a simple gradient created in PhotoShop. We could have used any other image or none at all.

The frames are a bit more complicated. If the frames had straight edges, there wouldn't be any problems, but in order to make the soft shadow independent of the page background, we need alpha channel transparency. PNG is the answer here, but unfortunately Internet Explorer 6 and below doesn't handle PNG transparency very well. Luckily than can be solved by the hack described later on this page.

XHTML

This part is pretty straight forward. We pack the image and the caption in a div with a class that is either thumbLandscape or thumbPortrait. It would be preferable to use the same class for all images, but that's not possible with this method.

CSS

body {
  background: #FC9 url(WarmGradient.png) repeat-x fixed bottom;
}

This is just the gradient seen at the bottom of this page. Be aware that fixed backgrounds means that scrolling requires more computing power than non-fixed. The gradient is entirely optional for our purpose and is just here to demonstrate the transparency of the shadows.

div.thumbPortrait, div.thumbLandscape {
	float: left;
	width: 240px;
	margin-right: 10px;
}

The trick to the flexible layout is quite simply the float: left;. The 17px is the width of the shadow plus 1 pixel for the black border.

/* Everything but IE */
body>div.thumbLandscape {
	background: url(Frame240x180_S.png) transparent no-repeat;
	padding: 77px 17px 1em 17px;
}
body>div.thumbPortrait {
	background: url(Frame180x240_S.png) transparent no-repeat;
	padding: 17px 17px 1em 17px;
}
}

We need to set the backgrounds for the two kind of images. However, if Internet Explorer sees this, it insists on using the background image without transparency, so we use the > selector. Internet Explorer 6 and below doesn't understand this and happily skips the definitions.

Well, that's it, not much to it. Unless, of course, we want to support Internet Explorer...

The rest of the CSS is specific to Internet Explorer. By exploiting the star bug, we can ensure that only Internet Explorer uses these definitions.

/* IE only, thanks to the star bug
http://www.info.com.ph/~etan/w3pantheon/style/starhtmlbug.html */
* html p.thumbImage a {
	display: block;
	cursor: pointer;
}

Remember that the use of AlphaImageLoader captures all interaction from the contained elements? By using the AlphaImageLoader on a link itself and by making the element display as a block, so that if fills the containing div, we can at least get that link to work.

* html div.thumbLandscape p.thumbImage a {
	padding: 17px 77px 1em 17px;
	height: 240px;
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=
'files/Frame240x180_S.png',sizingMethod='crop');
}
* html div.thumbPortrait p.thumbImage a {
	padding: 17px 17px 1em 17px;
	height: 185px;
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=
'Frame180x240_S.png',sizingMethod='crop');
}
* html div.thumbLandscape, * html div.thumbPortrait {
	width: 274px;
}

A little padding is added to align the image to the background, and we remember to set the height to avoid clipping. We also set the width for the entire block.

* html p.thumbImage {
	position: absolute;
}
* html div.thumbLandscape p.thumbImage a {
	padding-top: 77px;
}
* html p.thumbCaption {
	padding: 220px 15px 0px 15px;
}

We also want links in the caption to work, so we separate the image from the caption by making its position absolute. We adjust the padding depending on the shape of the frame and the position of the image inside the frame.

Caveats

This method requires a CSS entry and a shadow bitmap for all the different image sized used. This method does not work with Netscate Navigator 4.x or less. It might be best to avoid serving the stylesheets to that browser.

The CSS does not validate, but the non-valid parts are specific for Internet Explorer, so that shouldn't be a problem. If it is imperative to have validating stylesheets, the clashing parts can be placed in another stylesheet and called with conditional comments.

Maintained by Toke Eskildsen
Last updated February 23, 2005