{"id":167482,"date":"2014-04-03T15:24:20","date_gmt":"2014-04-03T22:24:20","guid":{"rendered":"http:\/\/css-tricks.com\/?p=167482"},"modified":"2017-04-12T17:39:26","modified_gmt":"2017-04-13T00:39:26","slug":"hassle-free-responsive-images-for-wordpress","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/hassle-free-responsive-images-for-wordpress\/","title":{"rendered":"Hassle Free Responsive Images for WordPress"},"content":{"rendered":"

Latest Update:<\/strong> The plugin has been merged into WordPress core. So if you’re running WordPress 4.4 or newer, you automatically have this.<\/p>\n

Update:<\/strong> The plugin created in this article has moved here<\/a> and now uses the more appropriate<\/a> srcset<\/code> attribute. It’s the official WordPress plugin of the Responsive Images Community Group and is endorsed by the WordPress Core Team. It sounds likely that this will make it into WordPress core eventually. Pretty cool!<\/p>\n

The following post is guest co-authored by Tim Evko<\/a> (@tevko<\/a>). 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.<\/em><\/p>\n

<\/p>\n

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.<\/p>\n

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

The Markup we ultimately want<\/h3>\n

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

UPDATE: The <picture><\/code> element is landing in browsers, so the plugin\/code in this article has been updated to work directly with that syntax.<\/div>\n
<picture>\r\n  <source srcset=\"examples\/images\/extralarge.jpg\" media=\"(min-width: 1000px)\">\r\n  <source srcset=\"examples\/images\/large.jpg\" media=\"(min-width: 800px)\">\r\n  <source srcset=\"examples\/images\/medium.jpg\">\r\n \r\n  <!-- fallback -->\r\n  <img srcset=\"examples\/images\/medium.jpg\" alt=\"alt text\">\r\n<\/picture><\/code><\/pre>\n

That is the basic markup pattern, although it can get slightly more complex<\/a> to accommodate some browser bugs.<\/p>\n

What we’re not<\/em> going to do is use that markup directly in blog posts, we’re going to get WordPress to help us with that.<\/p>\n

The Theme<\/h3>\n

All you need to do in your theme is make sure this one-liner is present in its functions.php file:<\/p>\n

add_theme_support('post-thumbnails');<\/code><\/pre>\n

This will ensure that your theme gives WordPress permission to resize the uploaded images. Without it, the plugin won’t work.<\/p>\n

The Plugin<\/h3>\n

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:<\/p>\n

<\/figure>\n

Adding the library<\/h4>\n

Queue it up responsibility:<\/p>\n

function get_picturefill() {\r\n  wp_enqueue_script('picturefill', plugins_url( '\/js\/picturefill.js', __FILE__ ));\r\n}\r\nadd_action('init', 'get_picturefill');<\/code><\/pre>\n

That will ensure WordPress loads up this JavaScript library on the front end.<\/p>\n

Define sizes<\/h4>\n

Tell WordPress what size images you want created upon uploading:<\/p>\n

add_image_size('large-img', 1000, 702);\r\nadd_image_size('medium-img', 700, 372);\r\nadd_image_size('small-img', 300, 200);<\/code><\/pre>\n

You can set this up however you like. add_image_size<\/a> 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:<\/p>\n

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.<\/figcaption><\/figure>\n

Making a [shortcode]<\/h3>\n

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:<\/p>\n

[responsive imageid=\"12\" size1=\"0\" size2=\"500\" size3=\"1000\"]<\/code><\/pre>\n

and it will output the markup we need for Picturefill. <\/p>\n

We’ll split this up into three functions. One to define the shortcode and what HTML to output, one helper to return alt text, and one specifically to loop through and output the image sources.<\/p>\n

function tevkori_get_img_alt( $image ) {\r\n    $img_alt = trim( strip_tags( get_post_meta( $image, '_wp_attachment_image_alt', true ) ) );\r\n    return $img_alt;\r\n}\r\n\r\nfunction tevkori_get_picture_srcs( $image, $mappings ) {\r\n    $arr = array();\r\n    foreach ( $mappings as $size => $type ) {\r\n        $image_src = wp_get_attachment_image_src( $image, $type );\r\n        $arr[] = '<source srcset=\"'. $image_src[0] . '\" media=\"(min-width: '. $size .'px)\">';\r\n    }\r\n    return implode( array_reverse ( $arr ) );\r\n}\r\n\r\nfunction tevkori_responsive_shortcode( $atts ) {\r\n    extract( shortcode_atts( array(\r\n        'imageid'    => 1,\r\n        \/\/ You can add more sizes for your shortcodes here\r\n        'size1' => 0,\r\n        'size2' => 600,\r\n        'size3' => 1000,\r\n    ), $atts ) );\r\n\r\n    $mappings = array(\r\n        $size1 => 'small-img',\r\n        $size2 => 'medium-img',\r\n        $size3 => 'large-img'\r\n    );\r\n\r\n   return\r\n        '<picture>\r\n            <!--[if IE 9]><video style=\"display: none;\"><![endif]-->'\r\n            . tevkori_get_picture_srcs( $imageid, $mappings ) .\r\n            '<!--[if IE 9]><\/video><![endif]-->\r\n            <img srcset=\"' . wp_get_attachment_image_src( $imageid[0] ) . '\" alt=\"' . tevkori_get_img_alt( $imageid ) . '\">\r\n            <noscript>' . wp_get_attachment_image( $imageid, $mappings[0] ) . ' <\/noscript>\r\n        <\/picture>';\r\n}<\/code><\/pre>\n

Then enabled the shortcode:<\/p>\n

add_shortcode( 'responsive', 'tevkori_responsive_shortcode' );<\/code><\/pre>\n

Ideally you define your breakpoints in the plugin here and then don’t pass them at all when using the shortcode, like:<\/p>\n

[responsive imageid=\"12\"]<\/code><\/pre>\n

Then only use the shortcode attributes in the rare cases you need to override the breakpoints.<\/p>\n

Altering the Media Uploader output<\/h3>\n

This shortcode will be tremendously useful (remember we can even adjust the markup to be the correct <picture><\/code> 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:<\/p>\n

function responsive_insert_image($html, $id, $caption, $title, $align, $url) {\r\n  return \"[responsive imageid='$id' size1='0' size2='600' size3='1000']\";\r\n}\r\nadd_filter('image_send_to_editor', 'responsive_insert_image', 10, 9);<\/code><\/pre>\n

Now selecting and inserting an image from the editor will work like this:<\/p>\n

<\/figure>\n

That’ll do it! Here you can see it working:<\/p>\n

<\/figure>\n

More you can do<\/h3>\n