I'm Michael Suodenjoki - a software engineer living in Kgs. Lyngby, north of Copenhagen, Denmark. This is my personal site containing my blog, photos, articles and main interests.

Article

Auto captions in photosUsing Javascript to add image caption from Alt attribute

Updated 2011.01.23 17:22 +0100

Ikke tilgængelig på dansk.

By Michael Suodenjoki, michael@suodenjoki.dk.

Version 1.2 May 2007.

Abstract

This article describe how you can define a JavaScript function to extract the caption text from the alt attribute of an img element and automatically add the caption text below the image/photo.

Note May 25th, 2007: I'm myself - on this webside - using a modified version of the javascript code described in this article. For one it is more browser-independent and have more features (they are not all described in this article). You can download the javascript file here. One thing to note is that a simple <img class="addcap" .../>  is enough if something a la

window.onload = function(e)
{
   addCaps();
}

is present in the document.

Update 27'th of May, 2008: I've discovered two articles describing a way to extract EXIF data via javascript. This sounds very promising and supplements this article well. See them at: Reading EXIF data with Javascript and jQuery EXIF data plugin.

Contents

1 Introduction
2 The addCaption function
3 CSS class definitions
4 Round of

Appendix A:  The JavaScript code

1 Introduction

I hate typing the same text twice - I guess that you do too. When you include an image or photo into your HTML page you typically want to write a caption to the photo. At the same time the Web Accessibility Content Guidelines tells you that must provide a description in the alt attribute of the HTML img element (see guideline 1, checkpoint 1.1 in the WCAG 1.0). The alt attribute should contain alternate text for browsers not displaying the image. However typically it is used as caption text for the image.

“I want to type the caption only once”

Since I often write the same image caption text - as I wrote in the alt attribute - in an following paragraph I often find that when the caption text changes I do forget to update the alt attribute text - or vice versa. I therefore wanted to write the text only once - namely in the alt attribute and then utilize JavaScript to append the image caption text automatically. So I have e.g. the following img element:

<img class="photo" 
     onload="javascript:addCaption(this,true)" 
     src="grandcanyon.jpg" 
     alt="Grand Canyon after sunrise."
     copyright="Photo | Michael Suodenjoki"/>

Example

The first photo do have the alternate text as prescribed by WCAG 1.0 but I have not written any caption text below it. The second photo is identical to the first left one, however it utilize the onload JavaScript function to append the caption.

Grand Canyon after sunrise. Grand Canyon after sunrise.

2 The addCaption JavaScript function

As you can see I have included a JavaScript call to a addCaption function when the image loads, my alternate (image caption) text and an "unauthorized" new attribute called copyright. The copyright attribute is my own invention and is supposed to include additional copyright information or photographer name for the photo also to be presented as part of the image caption. In newspapers you typically will see it as the photographers name and/or the bureau name holding the copyright right aligned below of the photograph. Also you can see the I have marked the img element with the CSS class "photo".

Now to the actual implementation of the addCaption JavaScript function (see code in appendix below). The function simply inserts a div element marked with CSS class 'caption' and into that div up to 3 child div elements, each marked with different CSS classes: caption-marker, caption-text and copyright. The div representing the copyright is only inserted if the copyright attribute text can be extracted from the img element.

Illustration of the inserted div elements below the img element.

The function has two parameters, the image element to add caption for and a boolean value telling the function whether it should use a caption marker. The caption marker I use is the quotation character "»" (Unicode character \u00bb), which I happens to like. You will notice that I've defined the caption marker as a separate div element. You could ask "why not simple prefix the caption text with the marker character?". The answer is that I would like the caption text to float right of the marker - not below it, as it would do if the caption text is wider than the image. The caption text in the above figure illustrates the idea. Of course these things can easily be controlled with the CSS classes used when it is defined as separate div class elements.

3 CSS class definitions

Of course you need to define proper definitions for the 4 different div classes used and your img (or img.photo) element. The following CSS code defines the classes for my elements:

/************************************************

                     PHOTOS

************************************************/
img.photo
{
  padding: 10px; 
  border: 2px darkgray solid;
}
div.caption
{
  color: darkgray;
  font-size: 95%;
}
div.caption-marker
{
  float: left; 
  margin-right: 0.2em;
  text-align: left;
}
div.caption-text
{
  float: left;
  clear: right;
  text-align: left;
}
div.copyright
{
  text-align: right;
  float: right;
  color: darkgray;
  font-family: "Franklin Gothic Book", Verdana;
}

4 Round of...

Well this pretty much sums it up. It is possible to utilize JavaScript to help you write only one. My code presented is not fully developed to work in all cases. A typical example involves using floating images, where the added caption text may not be added to present itself directly under the image. However it is rather straightforward to extend the code to include an extra div element around the image and caption. I leave this is an exercise...

Hope that you can use it.

PS. Some notes on XHTML validation...

My described method does involve the use of some invalid attributes for strict XHTML - the onload and copyright attributes being the most striking examples, however some would also argue that I'm using the alt (for alternative) attribute incorrectly since I do not write a true helpful descriptive text for the accessibility minded. While this is true I do prefer my method since it ensures that I, at least, write something meaningful text in the alt attribute. Earlier I often forgot that and I would argue that in 9 out 10 websites the text in the alt attribute is the exact same as any following caption text - so why not use it that way?

While you're at it you my want to read this thread at SimpleBits.

I've also discovered that I'm not the first one "inventing" JavaScript image captions  (you never are, right?), see http://www.1976design.com/ blog/archive/2003/11/25/captions/.

PPS. Wouldn't you love it if was possible to extract the EXIF information from a image at run-time using a standard client scripting language e.g. JavaScript?

Update 27'th of May, 2008: I've discovered these very interesting articles describing exactly what I was looking for : Reading EXIF data with Javascript and jQuery EXIF data plugin.

Appendix A: The JavaScript code

You can see the JavaScript function code below. I've tested in on IE6 and Netscape 7.01.

function addCaption( oImgElem, bUseCaptionMarker )
{
  // Insert Caption
  var oCaptionElem = document.createElement("div");
  oCaptionElem.className = "caption";

  if( bUseCaptionMarker)
  {
    var oCaptionMarkerElem = document.createElement("div");
    oCaptionMarkerElem.className = "caption-marker";
    var oCaptionMarkerTextElem = document.createTextNode("\u00bb");
    oCaptionMarkerElem.appendChild(oCaptionMarkerTextElem);
    oCaptionElem.appendChild(oCaptionMarkerElem );
  }

  var oCaptionTextElem = document.createElement("div");
  oCaptionTextElem.className = "caption-text";
  var oCaptionText = document.createTextNode( oImgElem.alt );
  oCaptionTextElem.appendChild(oCaptionText );
  oCaptionElem.appendChild(oCaptionTextElem);

  if( oImgElem.getAttribute("copyright") != null )
  {
    var oCopyrightElem = document.createElement("div");
    oCopyrightElem.className = "copyright";
    var oCopyrightText = document.createTextNode( 
      oImgElem.getAttribute("copyright") );
    oCopyrightElem.appendChild(oCopyrightText);
    oCaptionElem.appendChild(oCopyrightElem );
  }

  if(oImgElem.nextSibling) 
    oImgElem.parentNode.insertBefore(oCaptionElem,
      oImgElem.nextSibling);
  else
    oImgElem.parentNode.appendChild(oCaptionElem);

  with(oImgElem.style)
  {
    oCaptionElem.style.width = (oImgElem.width+borderLeft+
      borderRight+paddingLeft+paddingRight)+"px";
  }

  return true; 
}

Creative Commons License
This work by Michael Suodenjoki is licensed under a Creative Commons Attribution 3.0 Unported License.

Captions or cutlines are actually quite complex. You have to think about a lot of stuff. See for example cutlines, cutline components and cutline layout.

See e.g. also Wikipedia Manual Style on Captions