jCaption: jQuery Image Captions with Customizable Markup, Style and Animation

September 2, 2009
Development

Orginally Posted March 2, 2009 | Last Updated November 4, 2009

jCaption is a jQuery plugin designed to make adding captions to a page dead simple. It takes an image element and uses one of its attributes to build the markup for a caption. It allows for both arbitrary styling and markup.

Demo Image

Dealing with image captions on the web can be a big pain. The code structure for nearly any caption looks something like the following:

<div>
	<img src="image.gif" alt="" />
	<p>Caption Text</p>
</div>

While writing such markup for every image is merely an inconvenience for web developers, it is an impossibility for most of thier clients. Many clients use a web-based WYSIWYG editor to create and edit their pages through a CMS. It would be nearly impossible to expect them to add this markup around their images.

This was a problem I faced when building a site for a client. I found well-concepted solution in Captify, but I found it too restrive for my needs. I proceeded by writing a version that met the following requirements:

  1. Follow jQuery Conventions - Animations shouldn't be handled by passing in a string, instead arbitrary animations should be allowed.
  2. Markup Should be Arbitrary - Other than the tag that is required, other markup should be arbitrary.
  3. Optionally Allow Placement From Text-Editors - Web-Editors like tinyMCE or FCKditor allow users to align images to the left or right of text. Depending on the version, this is accomplished using the "align" attribute or "style" attribute. This plugin accomodates both and makes sure that the caption is correctly placed as well.

Using the plugin

Using the plugin is dead simple. Just use apply the .jcaption() method to the images you want:

$('img').jcaption();

By default this will take the following image:

<img src="image.jpg" alt="Some caption text" />

and produce the following markup:

<div class="caption">
	<img src="image.jpg" alt="Some caption text" />
	<p>Some caption text</p>
</div>

The options will allow you to control the elements and classes that the plugin produces. Additionally, to accomodate text editors, the plugin can copy the styling that was applied to the image to the caption instead, and take the images "align" attribute and append it to the caption class. So for text editors that place images using align="left" you can instead have the plugin add "left" as a class to the caption so that you can place the entire caption using your stylesheet.

Options

$('img').jcaption({
	//Element to wrap the image and caption in
	wrapperElement: 'div',
	
	//Class for wrapper element
	wrapperClass: 'caption',
	
	//Caption Element
	captionElement: 'p',
	
	//Attribute of image to use as caption source
	imageAttr: 'alt',

	//If true, it checks to make sure there is caption copy before running on each image
	requireText: true,
	
	//Should inline style be copied from img element to wrapper
	copyStyle: false,
	
	//Strip inline style from image
	removeStyle: true,
	
	//Strip align attribute from image
	removeAlign: true,
	
	//Assign the value of the image's align attribute as a class to the wrapper
	copyAlignmentToClass: false,

	//Assign the value of the image's float value as a class to the wrapper
	copyFloatToClass: true,

	//Assign a width to the wrapper that matches the image
	autoWidth: true,
	
	//Animate on hover over the image
	animate: false,
	
	//Show Animation
	show: {opacity: 'show'},
	showDuration: 200,
	
	//Hide Animation
	hide: {opacity: 'hide'},
	hideDuration: 200	
});

You'll see that any arbitrary animations are possible by setting up the options in this manner.

Demo

Demo Image

View a Demo of this plugin with and without animations here. The captions on the left are animated and the caption on the right is not.

Download the plugin

This plugin has been tested in IE 6 and 7, Firefox 2 and 3, Safari and Chrome.

Updated Sept. 2, 2009 - Added CopyFloattoClass, improved some documentation and changed defaults to reflect the current state of text editors.

Updated Nov. 4, 2009 - Added requireText, allowing the plugin to be run even if there is no caption text.

Download a zip of the plugin and the sample.

Comments

Chrisby's avatar
Chrisby
Would be nice for the copyAlignment to have the option to use bootstrap pull-left pull-right classes
Elana de Beer's avatar
Elana de Beer
Hi there. I love this plugin:).

I installed the plugin and it worked perfectly, until one day it stopped working.
On the page where I called jCaption I get the following JavaScript error:
"Uncaught TypeError: Object [object Object] has no method 'jcaption' main.js:20
event.returnValue is deprecated. Please use the standard event.preventDefault() instead. "

I am quite rusted with JavaScript and I just can't seem to figure out what I did wrong. I did not change the code at all.

This is the part where I call the plugin:
$('.single .article-container img').jcaption({
copyStyle: true,
animate: true,
show: {height: "show"},
hide: {height: "hide"}
});

The browser says the error lies in the first line. But I can not figure it out.
Joel Sutherland's avatar
Joel Sutherland NMC team member

Eric,

It is possible. I would suggest going into the plugin code itself to make the changes. The code is pretty simple and clear. You should be able to make your changes in just one or two places.

Eric Lofgren's avatar
Eric Lofgren

I'm trying to install both this and a lightbox/slimbox clone (actually picbox, http://bunnyfire.co.uk/projects/picbox/). The problem is the existing code structure, for the lightbox, uses a title tag in the anchor surrounding the image, i.e. the image's parent.

The second problem is less important but the entire div is enclosed in the anchor... jcaption only surrounds the image.

Is it possible to easily modify the code to:
1. Read the title from the parent of the image instead of the image
2. Enclose the anchor tag inside the div so only the image, not the caption, is linked

Thanks,
Eric

web design's avatar
web design

This is great and thanks for sharing, yeah it's like a project captify but both are not working for me in dynamic may b because jquery 3 or I dont know let me know is any other way for caption thanks in advance.

website laten maken's avatar
website laten maken

Very nice script! Have been looking for this some time and I think this one fits my needs perfectly! Thanks!

Will's avatar
Will

I love your script but I need to be able to a little bit more. I want the caption (image name) to be visible but when you put your mouseover the image the caption to move up to display the additional text on subsequent lines. I.e. It will display the image name but on mouseover will also display the image description... Is this possible? How would I achieve it?

Sample code would be:

<div class="project"><a href="#"><img src="images/img1.jpg" alt="A product name<br />This is this is the product description" /></a></div>

Leo Houer's avatar
Leo Houer

Hey,

How can i make the black semi-transparent background stretch over the whole image width, regardless of how long the caption text is?

I tried putting width=100% within div.caption p {} but that makes the semi-transparent bar strech over image width including border widht of the image. How can i make it so that its width is that of the image (without the img border)?

THANKS!

Joel Sutherland's avatar
Joel Sutherland NMC team member

Rachel,

This is likely happening because of the way that the crawler code loops the images.

The captions are only added when the page is first loaded. My guess is that the crawler duplicates images from the beginning when it gets to the end. This means that the caption plugin is not running on these new images.

Rather than using the jCaption plugin I suggest adding a <p> tag around the caption you want to pop up and place it inside the <a> tag. You can use the CSS I include to make it look right.

Then use the jQuery .live method (http://docs.jquery.com/Events/live#typefn) to add the sliding effect. The code would look something like:

$("mycrawler2 a").live("mouseover", function(){
$(this).children("p").slideUp();
).live("mouseoout", function(){
$(this).children("p").slideDown();
);

Rachel's avatar
Rachel

Hi,
I am trying to use the jcaption plugin along with an image crawler and am having some issues. Some of the issues have to do with padding or margins that the images are inheriting, I can't figure out from where.
The most outstanding issue is happening in Safari, after the crawler goes through the images once, the captions stop popping up, then they start again in the next round of images. I know this is a lot to delve into, but any help or tips would be welcome. Thanks!

you can see the markup here:
http://sdmedia.hyperarts.biz/index-withjcaption.html

Joel Sutherland's avatar
Joel Sutherland NMC team member

Ethan -- It looks awesome. You might also want to check out my post on jquery portfolios: http://www.newmediacampaigns.com/page/a-jquery-plugin-to-create-an-interactive-filterable-portfolio-like-ours

ethan's avatar
ethan

Hey Joel, wanted to let you know i got it working here: http://attunedesigns.com/portfolio/

thanks!

ethan's avatar
ethan

Yea! Hire me!

The inline issue is probably just because i haven't delved into the structure at all. I was able to throw them together with a left float actually!

Joel Sutherland's avatar
Joel Sutherland NMC team member

Ethan -- We will have to meet up!

I am about to release an update to this plugin that may solve your problems. Have you tried the CopyFloatToClass that Yvan Made?

ethan's avatar
ethan

And what are the chances i'm writing from the same town of CARRBORO!? I thought at first it was a mistake, like it was echoing my location.

ethan's avatar
ethan

I'm having a hell of a time getting an inline flowing gallery going with this one... anyone have any hints?

Displaying div.project as 'inline' breaks in IE6.

 Yvan's avatar
Yvan

Hi Joel,

I just changed your plugin to integrate the option CopyFloatToClass.

You can find the changes here: http://yvmarques.googlepages.com/jcaption.js"

 Joel's avatar
Joel

The caption is only written once. The code would need to be modified to allow updating. A good alternative for your project would probably be the cycle plugin. You can see that at: malsup.com/jquery/cycle/

 carlos's avatar
carlos

What if I want to change the caption text?. On a page I have a photo that changes every certain time, the photo changes but not the caption text, it shows me always the same

 Kevin's avatar
Kevin

Hello, I love the plugin!

But I think I found a bug?

In the demo page (using Firefox and Safari), if you hover over the linked images the cursor becomes pointer and images are clickable. But in IE7 IE8, the cursor doesn\342\200\231t become a pointer and can\342\200\231t click on the images, the link only works on the caption itself.

I hope this helps.

Kevin

 Joel Sutherland's avatar
Joel Sutherland

Jack,

Thank you for the catch on the autowidth. I will update the plugin to address this. Instead of measuring the image directly I need to temporarily wrap it and then measure the wrapper.

I am absolutely swamped at work though so I won't have this fix done immediately. In the mean time you can make the adjustment on line 71:

if(settings.autoWidth) div.width(image.width());

Let me know if you have any trouble.

 Jack Auses's avatar
Jack Auses

Great plugin! Is there a way to add extra width to the autowidth value? I'm currently using jcaption on a site and it's performing perfectly. However, my CSS calls for a 5px border around the image, increasing the total width of the image by 10px and slightle messing up my layout because the width of wrapper is 10px narrower than it needs to be. I'd like to be able to specify that jcaption assign a width to my wrapper div with a value of imageWidth + 10px.

Mustang's avatar
Mustang

the plugin is very nice, however I can't find a way to put html on the caption.

 Joel's avatar
Joel

Matty,

It should be possible -- could you send me a copy of the code you are having trouble with and I will take a look?

joel at newmediacampaigns dot com

 Matty's avatar
Matty

Good work.
Is it possible for me to have links in the caption?
Using an attribute just passes plain text..

Joel Sutherland's avatar
Joel Sutherland NMC team member

Nate,

It is very much like Captify, except that it only performs the 'core' function of creating captions. Everything else is optional.

As an example, Captify only allows certain kinds of animations. You specify 'fade' or 'slide'. With this plugin, any jQuery animation is possible because it follows the jQuery convention for plugin animations.

Another example is how this handles markup. This plugin allows you use any elements you wish to build your caption.

Ultimately the distinction is in flexibility. Captify is good at letting you do one type of caption. This lets you do any kind you wish, Captify's style included.

 Nate's avatar
Nate

this looks like http://plugins.jquery.com/project/captify"

Leave a comment