The [caption] shortcode in WordPress is a neat bit of functionality. It allows you to add captions to images. However, you are not limited to just adding captions to images. You can add them to pretty much anything, and you’ll learn how to do it by following this tutorial.
In this tutorial, I will walk you through using, designing, and customizing the output of the [caption] shortcode.
How to add images with captions
Many of you might already be aware of how to do this, but let’s cover the basics for those WordPress users who don’t.
To add an image caption, you must first upload an image using the WordPress media uploader. Once you’ve uploaded an image, you should see an input box labeled “Caption,” which is where you’d add your image caption, as shown in the following screenshot.

To insert the image with a caption into your post, you’d simply click the “Insert into Post” button just like you would with any other image.
What this looks like on the front end of your site will depend entirely on your theme’s design, but it will look something like the following screenshot.

That’s pretty much everything you need to know about the most common use of captions in WordPress. Keep reading though. You might learn a few more neat tricks.
How to add captions to other elements
Many WordPress users are unaware that captions can be used for more than just images. Yes, you can wrap any element with a caption. You can even wrap other shortcodes with a caption. In fact, let’s give that a try.
In this example, let’s wrap a Vimeo video using the [embed] shortcode with a custom caption.
When you normally embed a video using the [embed] shortcode, it would look like the following line of code in your post editor.
[embed]http://vimeo.com/14580921[/embed]
Let’s take one more step and add a custom caption. There are two requirements for using the [caption] shortcode: you must input both the width and caption attributes. Here’s what your new video/caption combo should look like in the the post editor:
[caption width="600" caption="A football video"][embed]http://vimeo.com/14580921[/embed][/caption]
When viewing the post on the front end of your site, you should see a caption for your video as shown in the following screenshot.

One thing I do need to note is that not all themes were designed to handle anything other than images within captions. This is simply because the most common use of captions is to wrap images. So, don’t be too hard on your theme developer if the design is a little off when trying this out.
[caption] attributes
The [caption] shortcode has several attributes that you may customize:
- id: A unique HTML ID that you can change to use within your CSS.
- align: The alignment of the caption within the post. Valid values are:
alignnone(default),aligncenter,alignright, andalignleft. - width: How wide the caption should be in pixels. This attribute is required and must have a value greater than or equal to
1. - caption: The actual text of your caption. This attribute is required, of course.
Let’s go back to the first example from this tutorial (adding an image caption) and look at the shortcode that WordPress added.
[caption id="attachment_6" align="alignright" width="300" caption="The Great Wave"]<img src="http://localhost/wp-content/uploads/2010/07/800px-Great_Wave_off_Kanagawa2-300x205.jpg" alt="Kanagawa" title="The Great Wave" width="300" height="205" class="size-medium wp-image-6" />[/caption]
As you can see, each of the attributes are used in this example. You can customize those attributes to your liking within the post editor.
Designing image captions
I’m not going to teach you how to design your captions (we might get Tung to do that in a later post). But, I am going to give you some basic CSS to start with. Let your imagination run wild.
Use the following classes in your theme’s style.css file to customize the appearance of captions.
/* The wrapper <div> for the caption and captioned element. */
.wp-caption { }
/* The caption text. */
.wp-caption-text { }
/* An image within the caption (you might want to style other elements too). */
.wp-caption img { }
One thing to keep in mind is that WordPress automatically adds an extra 10px of width to the caption using an inline style. You can either wrestle with styles for that or see the next section of this tutorial.
Customizing the caption output
WordPress allows you to modify the HTML output of the [caption] shortcode by using a custom filter on the img_caption_shortcode hook. You can use it to change up things however you want. In this particular example, you’ll learn how to fix a minor issue with captions.
If you’re a WordPress theme developer, you’ve likely had a headache or two from styling the [caption] shortcode in WordPress. Well, if you’ve ever tried to do anything other than the generic box around an image thing, you’ve probably hit some snags. WordPress adds 10px of extra width to its caption wrapper. I assume this was to make it easier to use the box-style captions. However, not all captions are designed to have a basic border and look all boxy.
The following code removes the additional 10px of width that WordPress would normally add.
add_filter( 'img_caption_shortcode', 'cleaner_caption', 10, 3 );
function cleaner_caption( $output, $attr, $content ) {
/* We're not worried abut captions in feeds, so just return the output here. */
if ( is_feed() )
return $output;
/* Set up the default arguments. */
$defaults = array(
'id' => '',
'align' => 'alignnone',
'width' => '',
'caption' => ''
);
/* Merge the defaults with user input. */
$attr = shortcode_atts( $defaults, $attr );
/* If the width is less than 1 or there is no caption, return the content wrapped between the [caption]< tags. */
if ( 1 > $attr['width'] || empty( $attr['caption'] ) )
return $content;
/* Set up the attributes for the caption <div>. */
$attributes = ( !empty( $attr['id'] ) ? ' id="' . esc_attr( $attr['id'] ) . '"' : '' );
$attributes .= ' class="wp-caption ' . esc_attr( $attr['align'] ) . '"';
$attributes .= ' style="width: ' . esc_attr( $attr['width'] ) . 'px"';
/* Open the caption <div>. */
$output = '<div' . $attributes .'>';
/* Allow shortcodes for the content the caption was created for. */
$output .= do_shortcode( $content );
/* Append the caption text. */
$output .= '<p class="wp-caption-text">' . $attr['caption'] . '</p>';
/* Close the caption </div>. */
$output .= '</div>';
/* Return the formatted, clean caption. */
return $output;
}
If you really want to try out something cool, try modifying the above code to use the <figure> and <figcaption> elements from HTML5.
Play around with some captions
Now that you’ve learned just about everything you need to know about captions, it’s time to go play around with them a bit.
I highly encourage WordPress theme developers to test out captions with elements other than images. I’m sure you could come up with some neat designs ideas.
I never knew these info (except for image caption
). Thanks for the details.
Thanks a lot for the code to remove the 10px injected by wordpress.
as for the HTML5′s “ tag, should this be done by core ?
It could be a while before HTML5 is completely integrated into core. I see no harm in theme developers adding it in where possible now, I’m going to tweak Justin’s function and use it in all my teams until WordPress catches up.
Very handy!
Do you know anything about captions and SEO? I would imagine search engines might appreciate that type of extra description to identify content.
Very informative – thanks Justin.
I was wondering which code syntax highlighter you use on this site?
Vayu
We actually don’t use a code syntax highlighter at all. We just wrap our code like so:
<pre><code>This is some example code</code></pre>Hi there, I have a problem with my captions and you can maybe help.
whenever I’m adding captions to my images, WP incapsulate them in a div that looks like this:
All my images are uploaded at maximum resolution and then scaled down with different stylesheets according to screen size but the caption always takes the width of the original picture.
How can I overcome this?
I obtained a few results by imposing an !important declaration on the various stylesheets but this is not ideal as pictures might have different widths and I would have to rethink the entire layout which is otherwise fine without captions.
Setting manually the width to auto not only is not recommended but it won’t work either!
Regards,
Matteo
Justin, I tried your video caption code but WordPress removed the caption when switching between the visual and HTML editor, or saving when in the visual editor.
You might want to submit a bug report for that on Trac.
Hey just a quick word to say thanks for this tutorial! The extra 10px added by the caption shortcode had indeed plagued me on a couple past projects. I really appreciate your solution.
Thanks for explaining more about captions. Do you have a solution for coding “hard returns” into a captions, so that I can break the line where I want, rather than just rely on the text wrap? I’ve been pulling my hair out all day over this one–thanks in advance for your advice.
I am using Alltuts wordpress theme for my website. When i set caption to any image it does not shown at all. even that image cannot locate at center with caption. Please help me, is there any need to do with my theme CSS?
I’m trying to get my TinyMCE/visual editor to display exactly like my front-end site. I’ve removed the 10px with this tutorial for the front-end. How do I remove it on the TinyMCE/visual editor?
Thanks a lot for posting this. I’ve had this really bizarre problem with WP eating my caption tags and not displaying them correctly, including converting them to unqualified div tags as above. I think your module plus the suggestion for converting them to straight-up html5 figure and figcaption tags is a much more elegant solution. Namaste!
How do you modify the image if it doesn’t have a caption? I’d like to wrap the image/linked image in a div if there is no caption.
Thanks Justin! Big help.
Great tutorial, thank you, it has proven useful. I discovered it through the Roots theme, which adds the as you suggested.
I’m currently trying unsuccessfully to add the description field into your code, I want both the caption and the image description to show. But being no code fundi, it’s a struggle.