The Captionator– Image Captions in HTML5 With figcaption and jQuery

Most of us want to be able to add image captions to images on our sites. Thankfully, in WordPress you can easily add or edit a caption using the standard media tools.

But, I’ve used other content management systems that did not have this feature built in. What to do? Write my own jQuery script, of course!

I was excited to find out that HTML5 provides the new <figure> and <figcaption> elements. The HTML5 spec says image captions are exactly what these elements are intended for. After doing a bit of reading on how those elements work, here is an example of the code I wanted my script to generate:

And here’s how I wanted it to look. HTML5 Image caption exampleLooks simple enough, doesn’t it? But, I soon found out things get tricky when you’re using a content management system without built-in support for captions. I still wanted it to be easy to upload and insert an image with a caption into a page.

The Solution – a jQuery Script

I wanted clients to be able to easily upload an image into their page using their content management system’s image upload dialog. Then they could mark the image as “having a caption” using a CSS class, along with supplying the caption text. Most content management systems will allow you to associate a CSS class and a TITLE with an image when you upload it. Here’s an example using the ExpressionEngine CMS upload dialog, using “caption” as the associated CSS class:ExpressionEngine CMS file upload dialog

I needed to write a JQuery script which would grab the image “marked” with that CSS class (“caption” in this example) and automatically generate the code for <figure> and <figcaption> around the original image. Here’s how the original <img> tag would look, as inserted by the content management system:

Putting it All Together

The script is easy to use; you can get it from Github here. I called it the “Captionator.” Take a look at my example page and you’ll quickly understand how to use it. The only tricky part is that you have to wait to execute the script until all of the images have been loaded, like this:

To use it in your CMS, you’ll need to load jQuery and call the captionate() method as the example shows. Then you can upload images using your content management system’s dialog. When you do, give the image a caption class and enter the caption text into the TITLE element. You can choose whatever CSS class you want; it doesn’t have to be caption.

Use it and let me know how it works for you! If you find any bugs or think of any useful enhancements, please let me know.


  1. says

    This looks pretty good. But when I create an image for my CMS I’m doing it with Markdown. The image markup looks like this:

    I’d like the assigned classes to be copied out to the surrounding tag. Possible?


  2. says

    Hey Bob, any CSS classes that you had originally assigned to the <img> should be copied out to the resulting <figure> that gets constructed. If you want something different than this, can you please show me what the generated code would look like?

  3. says

    I’m enjoying your captionate() and it does just what I need, and simply. One problem – it seems to write out something like:

    <figure style="width: 283px;"

    creating a fixed width image. Is it possible to turn that off?


  4. says

    Hi Bob, I’m glad you’re enjoying the Captionator script. The script will copy any existing styles that were previously assigned to the image, over to the <figure> that it generates. This is by design, so that styles will be preserved.

    So I’m guessing the content management system you’re using is generating the inline style with the fixed width, because a lot of CMS’s do that.

    The best way to fix this is to investigate if this behavior can be turned off in the CMS you’re using. This is an annoying feature of several CMS’s– it really gets in the way of building responsive websites!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href=""> <em> <s> <strong> <code> (use <code> for short code samples, or link to jsFiddle or Gist for longer ones).