Make wp-caption the same (responsive) width as the Image

Posted on

I was working on a problem last week in WordPress where the caption for an image was extending the whole width of the container, not staying the width of the image. This make sense – the image is inside the .wp-caption container. So how to we fix it? Let me tell you!

The first thing I tried was some nice, simple CSS:

.wp-caption {
   display: table;
}

.wp-caption-text {
   caption-side: bottom;
   display: table-caption;
}

WordPress places a paragraph around the actual caption text called .wp-caption-text, so what this CSS is saying is, “Treat .wp-caption like a table, and .wp-caption-text like a caption for the table. Place it on the bottom of the table.”

This actually works out great. The div is the width of its content (in this case, an image) but it’s not responsive. It doesn’t pay attention to max-width either. So back to the drawing board.

What I did, thanks to a push in the right direction from this post, is less elegant but actually works responsively. It involves using PHP and filtering the caption output to add a max-width style inline that is the same as the image’s width. Here’s the code below. It’s actually pretty similar to the code above, with one important difference:

function responsive_wp_caption($x = NULL, $attr, $content) {
    extract( shortcode_atts( 
        array(
         'id' => '',
         'align' => 'alignnone',
         'width' => '',
         'caption' => '',
        ), 
        $attr 
      )
    );
 
    if ( intval( $width ) < 1 || empty( $caption ) ) {
        return $content;
    }
 
    $id = $id ? ('id="' . $id . '" ') : '';
 
    $caption = '
';     $caption .= do_shortcode( $content );     $caption .= '

' . $caption . '

';     $caption .= '
';     $caption .= '
';       return $ret; }   add_filter( 'img_caption_shortcode', 'responsive_wp_caption', 10, 3 );

Take a look at where we first set $caption. This is where we set the max-width of the div to match the width of the image. We’re also adding in a width of 100% to make sure the div doesn’t get too small or too big depending on it’s child image.

One Thought

  1. Hi Joe, thanks so much for this snippet, it’s the clearest example I could find to solve this issue.
    Just needed to fix a typo to make this work.. the $caption variables (except the original $caption being concatenated) should be named $ret. Cheers!

Comments are closed.