The problem with images

You would have thought that captioning and positioning images on a web page would be very straightforward, but it is not entirely so. There are two problems: the <img> tag is an in-line element, and XHTML has (as yet) no caption tag for images similar to the <caption> tag for tables.

Adding captions semantically and positioning images using CSS

Trig point
Trig point at TQ422200, Founthill (flush bracket No S5101)

Being a standards purist, I have been searching for a satisfactorily semantic way of adding captions. I think Iíve finally found one thanks to an old (2006) blog from Nater Kane. He argued that since we use captions to describe what is represented visually in an image, using a definition list (<dl>) is the most appropriate solution to this issue, with the image as the term to be defined (<dt>) and the image caption as the termís definition (<dd>).

This is an elegant solution, as it creates a logical link between image and caption and keeps the mark-up rigorously semantic. The definition list is a block element, which makes positioning using CSS easy. And the solution works in practice.

Having found a semantic way of adding captions, the next problem was to position the images and style the captions using CSS. I wanted three options Ė image + caption floated to the right, image + caption floated to the left, and image + caption centred. I also needed to accommodate the two standard widths of image Iíve adopted, 240 px and 320 px.

Pevensey Levels
Pevensey Levels

My solution was to create five different classes that can be applied to the definition list, three to control position (imgleft, center, imgright) and two to declare the width (port [for 'portrait', 240 px wide], land [for 'landscape', 320 px wide]). [The class 'center' is simply a misspelling. It ought to have been 'centre', but it would be just too much effort to correct it now.]

Each definition list containing an image and its caption is assigned two classes, one for position and one for width. For example: <dl class="imgright port">, for an portrait orientated image (with a width of 240 px) to be floated to the right.

Separately, I created a class called imgcaption to style the definition (<dd>). Note that the text alignment of the caption is dealt with by the class applied to the definition list controlling position (imgleft, center, imgright), not by the imgcaption class.

To see an example of the mark-up, see the source for this page (Page > View source in Internet Explorer). And have a look at the associated cascading style sheet to see how the positioning and styling work.

Non-standard image sizes

Floated elements must have a declared width.

Occasionally I want to use a non-standard picture size. In these cases, I always centre the picture, to avoid the need to declare a width. The definition list containing the image and its caption is assigned only one class, 'center'.

Turner: Chichester Canal
Joseph Mallord William Turner: Chichester Canal, circa 1828 (Tate Collection)

Note that in this case, because no width is defined, the Caption does not neatly wrap to match the picture width. Not, I think, a serious defect.

Similarly, if I need two (or more) side-by-side images with a common caption, I simply centre the definition list by assigning it the class 'center'. In this case the term to be defined (<dt>) contains the two images, and the termís definition (<dd>) contains the common caption. Each image is given a different title, revealed as a 'tooltip' when the cursor is placed over the particular image.

North's SeatNorth's Seat
North's Seat - trig point

Pictures without captions

On some occasions I want to add pictures without captions - for example, the vignette of a plant I put between the sections of a page. In these cases, it is simplest to convert the image into a bock element by wrapping it in a paragraph tag (<p>). I always want these images centred, so the paragraph is assigned the class 'center'.

Ragged Robin

Top