Copyright © Michael B. Stevens 2002 - 2007 - all rights reserved. Last updated Jan. 13, 2007.
HOME
The form searches the entire domain of many subsites for one or more keywords. Use your browser's search function to search this web page.
domain map
Hammering the Thumbnails
A thumbnail is a little image that you click with your mouse to get an enlargement. Individual thumbnails or groups of them are often used on web pages, and one of the questions I most often see in web design newsgroups is "what is the best way to thumbnail"? The question actually has two parts: How do I make the little image, and what is the best way to do the enlargement?
How do I make the little image?
First, what not to do:
Never start with a large image and depend on the browser to display it as a small image. Say that you had an image (someFullSized.jpg) that is 600 pixels high and 600 pixels wide. You should not do this:
<img src="someFullSized.jpg" height="90" width="90" alt="what not to do" title="the horrible thumbnail kludge" />
This defeats one of the most important purposes of a thumbnail -- fast download time. Remember that a very large proportion of visitors to most sites do not use broadband access. Using this horrible little kludge requires as much time to download as the full sized image would take. Sadly, it is all over the net.
Instead, do this:
Resample the full size image by pulling it into your image enhancement software and creating a smaller copy of the image. If you don't have this software, you can download it for free -- go to a search engine and search for Gimp, Lview, or Irfanview for starters. Each software package has a different place on the menu for this. Make a new image that is a rescaled version of it. Dig around in the package until you find something that will make this scaled down copy from the image. Changing the "view" of the software is not what you want to do. Scale the image to the actual size that you want it to display on the webpage.
What if you have a large directory of similar images and don't want to work with each one individually? Packages also exist to do this. Dreamweaver can do it, and Perl's ImageMagick module has the tools in it if you want to experiment with writing your own.
Pay attention to the aspect ratio.
The aspect ratio is the relationship between the width and the height. For instance: If you have an image that is 500 pixels wide and 100 pixels high, you can reasonably convert it to a thumbnail that is 50 pixels wide and 10 pixels high, but not to an image that is 50 pixels wide and 20 pixels high. The image will be stretched vertically. I occasionally see distortions used for some specific artistic effect, but on most sites changing the aspect ratio is a mistake. Divide both the height and width by the same number to get your target size for the new thumbnail image.
A detail might be enough.
Sometimes it is effective to use a detail from a larger image
instead of a thumbnail of the entire image. In this case the detail was reduced in size, too, but
this doesn't always have to be the case. Make the detail
relevant, too! Use the part of the image
that conveys the most useful information.
Keep it the right size for the image.
You want the thumbnail to be big enough to allow the visitor to decide whether she wants to click through to the enlargement -- some images require larger thumbnails than others, and a human choice is required. You also don't want to make the thumbnail too large, because this will slow download time. So don't rush through the task of making thumbnails -- take a bit of time to experiment with your images. Do not use software that automatically thumbnails a directory of images unless the images are alike in their size requirements.
Optimize both the thumbnail and the full sized image.
The thumbnail may not require as detailed an image as the thing it stands for. A 1-bit black-and-white thumbnail may represent a 24-bit true-color image, if all you're looking for is a key to the subject matter of the enlarged image.
Many .jpg images allow you to save at lower than 100% quality
with a great savings of download time and very little visual
degradation to the human viewer. If you have plenty of time,
clear your browser's cache and
time the download of this 4K - 70K thumbnail/enlargement pair saved at 100% quality
by the Gimp program .
Clear your cache again and compare download time to this 2K - 49K
thumbnail/enlargement pair at 33% quality:
On a dial up connection, the first pair causes a really painful
wait. The lower quality pair is definitely the better choice. But if you were
displaying an artist's work you might want to stick with
the highest quality image. It's a judgement call that only you can make.
Don't depend on software that automates image resizing
if your images differ in their optimization needs. If your web pages are on the internet,
you must face the fact that many visitors will not be on broadband.
Different software packages use different scales for .jpg quality. As you work with them, judge the quality of images saved with your eye until you know the package very well.
Don't thumbnail at all!
Use normal anchors, like the ones at rstoutart.com, near a thumbnail sized image. The anchors can be descriptive, or can give the size of the targeted image. This is especially useful if you have several sizes of enlargements to make available.
Get a group of thumbnails onto a page the right way.
Ah! Standardization Wars. This important problem needs more minute scrutiny than we have room for here. Instead, here are some resources you can use to design your page:
- thumbnail layout
- table-less layout with CSS
- advanced CSS layout
- subtleties of CSS boxes
- Tables are Dead. Long Live Tables
- Toss Out Your Tables
- CSS Positioning
- Layout Reservoir
- my portal -- search under CSS, Web Design, and XHTML in the pull down menu
- World Wide Web Consortium -- an extremely important site
Putting the thumbnails and their descriptions in divisions or lists styled with CSS is often the best choice. They are usually more accessible and degrade more gracefully.
The choice of links may make you think that I'm totally against tables. Not true. I am opposed to tables used for display purposes, or for the layout of an entire page. But within a non-tabular page, actual tabular data should be inside a table. One of the symptoms of true tabular data is that each cell is associated with other cells in a meaningful way. Think of a spreadsheet, or of a TV Guide page, or of matrix algebra. A thumbnail with a description just barely meets the requirements of tabular data, so you can go with tables if you want. Thumbnails and their descriptions can be related to each other either down columns or across rows.
A table will not wrap like text. Horizontal scroll bars appear as information disappears behind the browser window. Things get ugly and hard to use quickly. If there are many images, associating thumbnails with descriptions across rows works better. Use only one thumbnail/image pair to a row. Groups of unlabeled thumbnails should not be put into a table unless the raw images somehow refer to each other in ways that are truly tabular. Do not hard code the width of table elements (td{width:100px;}) -- use percentages instead (td{width:10%;}). Let them stretch and compress to meet the size of the visitor's browser window -- which is going to vary quite radically from one visitor to the next.
Styling thumbnails
All sorts of stylings are possible. Here's the line that changes them on mouse hover for this tutorial:
a img:hover{border: 3px solid #f07;}
This makes only images that are inside anchors change behavior on hover. In this case the border color changes. Here's a link to the entire style sheet.
What is the best way to do the enlargement?"
Simplest and ugliest:
This method is OK for a quick and dirty page,
but it looks raw and unfinished with the image crammed up into the upper left corner of the window.
It works in most browsers,
and is done with the following code:
<a
href="images/11.jpg"
title="simplest">
<img
src="images/1.jpg"
width="50"
height="41"
alt="tiny flower"
title="Simplest way" />
</a>
Some designers also include target="_blank" so that the image displays in a new window.
This causes accessibility problems for some visitors, so don't do it.
Ugh! JavaScript pop ups:
If you have your browser set to accept pop up windows, and if you have JavaScript turned on you can try clicking the following image:
Pretty cool, huh? But there are problems. Many visitors have their browsers set not to accept pop up windows
because they have been irritated by advertising. Others have no JavaScript, or have their JavaScript turned off. In this case
the script degrades gracefully to the 'Simplest Ugliest' method.
But there are still the accessibility problems that come with opening a new window, so you need to warn the visitor, somewhere near the thumbnail, that this will happen. This can be done with something like the following code:
<a href="images/11.jpg"
onclick="window.open('images/11.jpg','flowerwin','width=500, height=406'); return false;">
<img src="images/1.jpg" width="50" height="41" alt="flower" />
<br />(Image opens in a new window.)<br /></a>
Some visitors with JavaScript on will still have trouble accessing the new window. Visually impaired visitors, visitors using text only browsers, and visitors using handheld devices can have trouble using pop ups. For this reason, there is a trend away from the use of pop up windows.
The best way without server side privileges:
Just write a little HTML (or better, XHTML) file to display the image:
The call to the file looks like this:
<a href="images/11.html">
<img
src="images/1.jpg"
width="50"
height="41"
alt="flower" />
</a>
The file that displays the image looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Image display file</title>
<style type="text/css">
body{background-color:#888;font-family: Verdana, Arial, Helvetica, Sans-serif;text-align:center;}
.rr{color:white;} .bb{color:yellow;}
a{color:#bfb;}
a:hover{color:#f07;}
.tabst{text-align:center;background-color:$888;padding:5%;border: solid 1px #ff0077;}
.xim{border-style:solid; border-width:30px; border-color:#444;}
p{font-family: Verdana, Arial, Helvetica, Sans-serif;color:#dddddd;margin:0px auto;}
</style>
</head>
<body>
<p>
<img src='11.jpg'
width='500'
height='406'
class='xim'
alt='flower'
title='html version of display' /></p>
<p>Enlargement of flower</p>
</body>
</html>
This displays the image nicely centered with a border. A grey, black, or white background will not have a color clash with any image. You might want to consider this if you plan to use the same background color on many images. Or, you may want to change the background color particularly to suit each image. Once you have one image display file you like, you can use it as a template and easily modify other image display files to work with other images.
Still, if your site is any size at all, it will become tedious modifying the template for tens or hundreds of images. There must be a better way yet.
Finally, the Mother Lode:
For a site with many images, the best solution is a server side program to display them. This can be done in Perl, PHP, or other server side languages. If you don't already have a server side language under your belt, this is the perfect first project to use in learning one. The following program happens to be in Perl, but any server side web language will do.
The idea is to pass the same information to the program as you would need to write an HTML (or XHTML) file to display the image yourself. So, you'll need to pass it the image's name, file type (.jpg, .gif, or .png), location, width, height, alt text, the background color to display behind the image, and the border color to display around the image. Once the program has this information, it can figure out how to display the image more easily than you ever could, and it will display the image almost immediately in the visitor's browser. The result will be something like the following thumbnail and enlargement:
You can use the program to display every enlargement on a site. Instead of many files to display the images, you will just make calls to the program from the thumbnail. Here's the code from the thumbnail above:
<a
href=
"image.pl?img=2::11::1::500::406::444::888::flower::enlargement">
<img src="images/1.jpg" width="50" height="41" alt="flower thumbnail" />
</a>
Not much work for each thumbnail/enlargement pair at all. You can download server side programs that will display images from CGI Resource Index, from PHP Resource Index and other places on the net. But the best way is to write your own.
Let's look at some of the details of a Perl program. The program starts with:
#!/usr/local/bin/perl -wT
use strict;
use CGI ':standard';
$CGI::POST_MAX=80;
my $pval=param('img');
my ($idirnum,$inam,
$itype,$iwidth,$iheight,
$colorborder,$colorbg,
$thealt,$description);
($idirnum,$inam,
$itype,$iwidth,
$iheight,$colorborder,
$colorbg,$thealt,$description)=split(/::/,$pval);
This part is just the basic setup. The first two lines give the location of the Perl interpreter and set up things so that you are not allowed to make large security mistakes like allowing untested data entered by a visitor to be used. The third line tells the interpreter to use the CGI module, which knows how to interpret information coming from the visitor's browser and how to write to the visitor's browser. The fourth line sets a limit on how long the line of information can be from the visitor's browser. The rest of the lines stuff variables with the information coming from the visitor. It splits a variable off at each '::' it finds in the input string. So, by this point, we already have a complete set of variables that can be interpreted by the Perl program to display the image. Your own program will probably use a somewhat different set of variables depending on your own preference in naming conventions for image files and your site setup.
my $ibwidth = ( ($iwidth+$iheight) / 40); #calculate a border width
This line calculates the border width to be displayed around the image by using the image's width plus height divided by 40.
You don't want to just use an image file address a visitor has entered -- there are ways for crackers to do nasty things if you do; the address needs to be detainted. Notice that on the first line of the program I uset -wT. The T turns on Perl's very useful taint mode. I also limited the size of the user input with $CGI::POST_MAX=80;. All that is not always enough insurance against crackers, though. One easy additional method is to use some predefined image directory addresses. These can be stored in an array, and the path to the image can be an index into the array that the XHTML file passes as a number. You'll have to consult a CGI/Perl book to decide just what detainted method you want to use given your particular naming conventions and programming habits. It usually takes only a few of lines of code to get things working.
Once we have a safe pathname to the image ($pathstr here) we can start writing the XHTML to the browser with what is called a 'here' document. It writes to the visitor's browser just like normal XHTML mark up, but when it encounters one of the variables that begin with a dollar sign, it interprets the variable and writes its value. For instance, it would write <height='20'> for <height=$iheight> if the user passed 20 as the $iheight variable. Other than that, everything is just about the same as the mark up you would write for an XHTML file to display the image, but instead of reading from a file, the program is writing the XHTML to the visitor's browser on the fly. The CGI module actually has functions that allow you to do similar things with much less code, but I prefer to work with CSS, and want complete control of my mark up.
The section that displays the image looks like this:
print "Content-type: text/html\n\n";
#the next statement is the beginning of a "here" document.
print <<"HTML CODE"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>mb stevens domain CGI generated image page</title>
<style type="text/css">
body{background-color:#888;font-family: Verdana, Arial, Helvetica, Sans-serif;text-align:center;}
.rr{color:white;} .bb{color:yellow;}
a{color:#bfb;}
a:hover{color:#f07;}
.tabst{text-align:center; background-color:#888; padding:5%;border:solid 1px #f07;}
.xim{border-style:solid; border-width:30px; border-color:#444;}
p{font-family: Verdana, Arial, Helvetica, Sans-serif;color:#dddddd;margin:0px auto;}
.tiny{font-size:80%;}
</style>
</head>
<body>
<p>
<img src='$pathstr' width='$iwidth' height='$iheight' class='xim' alt='$thealt' title='$description' />
</p>
<p>$thealt</p>
<p><span class="tiny">Perl/CGI generated XHTML 1.0 Strict</span></p>
HTML CODE
#...which is the end of the 'here' document.
You may have noticed that the 'here' document mixes XHTML markup with program code on the same page. This matters little with such a short script. If you want to investigate cleaner ways of generating a web page, have a look at this article.
Finally, we add a little subroutine to handle errors:
sub Errmsg {
print "Content-type: text/html\n\n";
print "$_[0]\n: $!\n";
exit;
}
... and that's it! You'll have to modify the code to work on your own server. Head for the nearest used bookstore and pick up a few tomes on Perl and CGI, and particularly Perl in conjunction with CGI before trying to make the mods. The same kind of thing can be done in PHP, Java, and in various proprietary languages, too. Once you get the concept, it's merely a matter of putting the parts together.
Getting the Visitor Back Whence She Came
In my examples, I've simply ignored the problem, assuming that the visitor will use her browser's back button or back arrow. I believe this is quite sufficient.
On some sites, it might be useful to have a 'back' link near the enlarged image, too, to speed the visitor's experience. You never know where the visitor comes to a page from, so you have to depend on the history kept by the visitor's browser. You can't read the history list, so you can't display the address the visitor came from; but you can tell the browser to move through the history list.
This can be done with JavaScript, using:
<a href="javascript:history.go(-1);">Back<a>
This is fine as far as it goes, but if the visitor has JavaScript turned off, then you have a back link sitting on your page that doesn't work. You could try warning such a visitor in a noscript tag, "Your JavaScript is turned off, use your browser's back button." But this is awkward -- there must be a better way.
There is: just generate the link itself with JavaScript. That way the link won't even appear unless the visitor has JavaScript turned on. To give the tiny program maximum compatibility with different versions of HTML / XHTML, let's put it in a separate file called, say, backlink.js and call it from your page with:
<script type="text/javascript" src="backlink.js"></script>
And here is the content of the backlink.js file:
document.write('<a href="javascript:history.go(-1);">Back</a>')
This could fail if the visitor has JavaScript enabled but has browser's history turned off or blocked with security software. Still, this is about as close as one can get to emulating a back button seamlessly. Coding and mark up purists will rightly describe the technique as a kludge. I leave it to you to decide whether convenience should override kludginess on your enlargement page.
You may ask, What if the page is generated by Perl or some other server side language? Can I generate the JavaScript as I generate the HTML? Yes you can, but it gets a bit complicated under XHTML. An easier solution is to make use of the environment variables used by your server side language. In Perl, the CGI.pm module uses HTTP_REFERER to find its way back to the page that called the program. You simply test whether the variable is available, and if it is, use it to print a link:
if ( $ENV{'HTTP_REFERER'}) {
$referer= $ENV{'HTTP_REFERER'};
print qq(<p><a href="$referer">Go to the Page You Came From</a></p>);
}
This variable may not always be available; but since we test for the variable's existence, the link will simply not show up if the variable is not there. Whatever server side language you are working with will probably have some variant of this trick.
Note, however, that the link is actually a forward link, even though the visitor goes to the page she came from. This means that her browser's back button won't work in the expected way if she wants to go further than the page she came from. To hopefully avoid this confusion, we said Go to the Page You Came From instead of Back in the link text. Another problem is that the HTTP_REFERER information could also be incorrect in some cases.
You may begin to see why I say that it is quite sufficient to let the visitor find the browser's back button instead of trying to interfere.
Your Input
Tell me if you have useful information related to thumbnails. If you think I've got the page right, let me know, and if you want to grumble at me for getting something wrong, I need to know what it is.
HOME
The form searches the entire domain of many subsites for one or more keywords. Use your browser's search function to search this web page.
domain map
Copyright © Michael B. Stevens 2002 - 2007 - all rights reserved. Last updated Jan. 13, 2007.
XHTML 1.0 Strict and CSS Thanks to Daniel R.Tobias for some corrections in the section on JavaScript pop ups. and to J. Korpela for a post clarifying a confusion concerning back button emulation. Illustration at the top is by Michael B. Stevens