Hassle Free Responsive Images for WordPress

The following post is guest co-authored by Tim Evko (@tevkor). WordPress has a built-in media uploading system. When you upload an image, it automatically creates and saves different versions of it. Tim will show us how we can customize and exploit that ability to help us with responsive images in content.

If you’re like me, and you’re tasked with building responsive website that’s relatively easy to update, WordPress is most often the CMS you will be building that website on. If you’re more like me, you probably skipped over a responsive image solution in favor of making things easier for whomever will be doing the updating. Fortunately, with a few lines of PHP and some JavaScript, you can now add automatic responsive image functionality to your WordPress site.

Here I’ll show you how to add support for responsive images to your WordPress site in the form of a small WordPress plugin.

The Markup we ultimately want

We’ll be using the Picturefill library here. For now, we’ll use the markup that library suggests, which closely mimics what the <picture> element will soon be.

<span data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
  <span data-src="small.jpg"></span>
  <span data-src="medium.jpg"     data-media="(min-width: 400px)"></span>
  <span data-src="large.jpg"      data-media="(min-width: 800px)"></span>
  <span data-src="extralarge.jpg" data-media="(min-width: 1000px)"></span>

  <!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
  <noscript>
    <img src="small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
  </noscript>
</span>

Eventually we can update all this to use the <picture> syntax once Picturefill is ready for it.

What we’re not going to do is use that markup directly in blog posts, we’re going to get WordPress to help us with that.

The Theme

All you need to do in your theme is make sure this one-liner is present in its functions.php file:

add_theme_support('post-thumbnails');

This will ensure that your theme gives WordPress permission to resize the uploaded images. Without it, the plugin won’t work.

The Plugin

This makes sense to do as a WordPress plugin, because we’ll want to keep it active no matter what theme is active. We can make it a folder with a PHP file in there to be the plugin code itself, and a copy of the Picturefill library:

Adding the library

Queue it up responsibility:

function get_picturefill() {
  wp_enqueue_script('picturefill', plugins_url( '/js/picturefill.js', __FILE__ ));
}
add_action('init', 'get_picturefill');

That will ensure WordPress loads up this JavaScript library on the front end.

Define sizes

Tell WordPress what size images you want created upon uploading:

add_image_size('large-img', 1000, 702);
add_image_size('medium-img', 700, 372);
add_image_size('small-img', 300, 200);

You can set this up however you like. add_image_size has a variety of parameters you can adjust. In the case of a 1024×768 bunny rabbit JPG I uploaded, a bunch of versions get created:


The 936×702 one was created because we specified we wanted one with a max of 702 height. The 150×150 one was created because WordPress automatically makes a square thumb of that size.

Making a [shortcode]

Let’s extend this plugin, giving it some real functionality, by making a responsive images shortcode. That way we can put this right in the post content:

[responsive imageid="12" size1="0" size2="500" size3="1000"]

and it will output the markup we need for Picturefill.

We’ll split this up into two functions. One to define the shortcode and what HTML to output, and one specifically to loop through and output the image sources.

function getPictureSrcs($image, $mappings) {
  $arr = array();
  
  // Loop through all of our images sizes and store each one of them as a php variable, In which each image size corresponds to a specific type. Mappings is defined later on
  foreach ($mappings as $size => $type)
  {
    // we're using 'wp_get_attachment_image_src();' to get the image we uploaded
    $imageSrc = wp_get_attachment_image_src($image, $type);
    $arr[] ='<span data-src="'. $imageSrc[0] . ' "data-media="(min-width:'. $size .'px)"></span>';
  }
  return implode($arr);
}
  
// Enable the [responsive] shortcode
function responsiveShortcode($atts) {

  extract(shortcode_atts(array(
  // In this array, we're creating the parameters to be passed into the shortcode tag  
    'imageid'    => 1,
    // You can add more breakpoint sizes for your shortcodes here. The current values being assigned here are our default values, which the shortcode will ovveride
    'size1' => 0,
    'size2' => 600,
    'size3' => 1000,
  ), $atts));

  // Here we're defining our mappings to be stored as variables, so we can declare whatever size we want in our shortecode 
  $mappings = array(
    $size1 => 'small-img',
    $size2 => 'medium-img',
    $size3 => 'large-img'
  );

  // Then we pass in the responsive image function, and print out the new responsive image tag with our shortcode variables included
  return 
    '<span data-picture>'
      . getPictureSrcs($imageid, $mappings) .
      // this noscript tag contains our default image for old / JavaScript-less browsers, and we're using size2 as our default
      '<noscript>' . wp_get_attachment_image($imageid, $size2) . '</noscript>
    </span>';
}
add_shortcode('responsive', 'responsiveShortcode');

Ideally you define your breakpoints in the plugin here and then don’t pass them at all in the shortcode, like:

[responsive imageid="12"]

Then only use the shortcode attributes in the rare cases you need to override the breakpoints.

Altering the Media Uploader output

This shortcode will be tremendously useful (remember we can even adjust the markup to be the correct <picture> in the future programmatically). But, how do we know the image ID to use? The Media Uploader UI doesn’t make that information available. It knows that ID though, and with a simple filter we can adjust what gets sent to the editor:

function responsive_insert_image($html, $id, $caption, $title, $align, $url) {
  return "[responsive imageid='$id' size1='0' size2='600' size3='1000']";
}
add_filter('image_send_to_editor', 'responsive_insert_image', 10, 9);

Now selecting and inserting an image from the editor will work like this:

That’ll do it! Here you can see it working:

More you can do

  • If you’re looking for a wider range of support, consider installing Matchmedia.js as well. It will make @media queries start working in older browsers, which then automatically makes Picturefill work as well.
  • Rather than use shortcodes or adjust the media uploader output, you could make this work with a special image field via Advanced Custom Fields.
  • You could adjust the markup to allow for align-* as WordPress likes to do. Or with <figure> and <figcaption> elements. Also, alt tags.
  • You could have the settings for the breakpoints be settable via UI that the the plugin creates, rather than hard coded into the plugin.

Here’s the GitHub repo if you want to contribute.


Hassle Free Responsive Images for WordPress is a post from CSS-Tricks

This entry was posted in Article, Syndicated. Bookmark the permalink.

Comments are closed.