RICG Responsive Images Plugin is a Game Changer

This one is for the more advanced front-end developers in the group. Thanks to the work of the Responsive Images Community Group and a few WordPress plugin developers, there's a new plugin available in the official WordPress plugin repository that I recommend to everyone: RICG Responsive Images. It's free and awesome. Go get it right now.
Responsive Images WordPress Plugin.
25 Feb 2015

Responsive Images WordPress Plugin

/
Posted By

A new plugin is bringing automatic default responsive images to WordPress, thanks to some talented and motivated developers. Responsive images are one of the last major hurdles facing developers in fully-optimizing websites for a variety of devices.

Before we go any further, stop reading and go get the Responsive Images WordPress Plugin right now.

Responsive Images RICG.

What are responsive images?

The term refers to the practice of delivering alternate image data based on device capabilities. That is: large-screen devices are served a large image, medium-screen devices are served a smaller image, and small-screen devices are served a small image.

It’s important to note that this isn’t just hiding and showing images based on screen size, the way we might with text blocks or other HTML elements. Responsive Images provide a way to selectively download the right asset for the right device.

Responsive Images: HTML Spec.This selective downloading prevents wasted bandwidth and optimizes display for both screen and print.

There are two methods to do this. Both are already built into the HTML spec: the <picture> element and the srcset and sizes attributes. This plugin uses the latter.

How does the responsive images WordPress plugin work?

Some serious under-the-hood magic. It does two things: (1) it hooks into WordPress’ <img> output and adds the proper attributes, and (2) it auto-generates multiple sizes of each image uploaded through the Media Library.

From the plugin’s documentation:

This plugin works by including all available image sizes for each image upload. Whenever WordPress outputs the image through the media uploader, or whenever a featured image is generated, those sizes will be included in the image tag via the srcset attribute.

A note on backwards compatibility: the plugin is not yet entirely retroactive.

Responsive Images Plugin Documentation on Github.

The responsiveness applies only to images uploaded after the plugin is activated and to Featured Images uploaded before the plugin was activated. Here’s how the plugin author described it:

The plugin is designed to be backwards-compatible, meaning that images added before the plugin was installed will be responsive when added to a post or “Featured Image” section. This is because it uses the image sizes previously defined by WordPress and the active theme’s functions.php file.

Why I’m excited about it

WIlto.

MFW feeling good about responsive images.

Mostly, the reason is ease of use. Responsive images are the future of the web.

It’s going to happen.

And this plugin just made it a lot easier for average WP authors to make it happen.

And I predict that sometime this year or next, the WP dev team will incorporate this functionality into the core. They’re already auto-resizing images. The simple last step is to modify the markup output to allow for this responsiveness.

Serious kudos and thanks to plugin authors Tim Evko, my friend Mat Marquis, and the other authors/contributors.

Responsive Images Plugin Contributors.

 

Update on WP 4.4

As of WordPress 4.4, images are responsive by default. If you are on WordPress 4.4 or plan to update, you will not need to install this plugin.

If you have had this plugin installed since before version 2.5 but are running version 4.4 of WordPress, it is important that you leave the plugin installed. This is because all versions of the plugin before version 2.5 relied on a data-sizesattribute being present on an image in order to provide the responsive markup needed.

If the plugin in this case is removed, then images in posts will be left with invalid markup. We are working to address this issue, and you can keep track of the plugin’s progress here.

You can still use the plugin for advanced image compression support or as a simple way to include the picturefill script. The plugin will fall back to WordPress default functions if responsive image support is detected in your installation.

Advanced Image Compression

Advanced image compression is an experimental image editor that makes use of ImageMagick’s compression setting to deliver deliver higher quality images at a smaller file sizes.

As such, ImageMagick is required for this feature to work. To learn more about the actual compression settings being used, read Dave Newton’s excellent writeup at Smashing Magazine.

To enable, place the following code in your functions.php file

function custom_theme_setup() {
	add_theme_support( 'advanced-image-compression' );
}
add_action( 'after_setup_theme', 'custom_theme_setup' );

Known issues:

  • Some people have encountered memory limits when uploading large files with the advanced image compression settings enabled (see #150).

Function/Hook Reference

Some docs on the functions used in this plugin.

 

Function wp_get_attachment_image_srcset

wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null )

Retrieves the value for an image attachment’s srcset attribute.

Return: (string|bool) A srcset value string or false.

Parameters

$attachment_id (int) Image attachment ID.

$size (array|string) (Optional) Image size. Accepts any valid image size (‘thumbnail’, ‘medium’, etc.), or an array of width and height values in pixels (in that order). Default ‘medium’.

$image_meta (array) (Optional) The image meta data as returned by wp_get_attachment_metadata(). Default null.

Uses

wp_calculate_image_srcset()

Usage Example
<?php
$srcset_value = wp_get_attachment_image_srcset( 11, 'medium' );
$srcset = $srcset_value ? ' srcset="' . esc_attr( $srcset_value ) . '"' : '';
?>

<img src="myimg.png"<?php echo $srcset; ?> sizes="{{custom sizes value}}">
Note

By default, the maximum width of images that are included in the srcset is 1600 pixels. You can override this default by adding a filter to max_srcset_image_width.

 

Function wp_calculate_image_srcset

wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id = 0 )

A helper function to calculate the image sources to include in a srcset attribute.

Return: (string|bool) The srcset attribute value. False on error or when only one source exists.

Parameters

$size_array (array) Array of width and height values in pixels (in that order).

$image_src (string) The src of the image.

$image_meta (array) The image meta data as returned by wp_get_attachment_metadata().

$attachment_id (int) (Optional) Image attachment ID. Default 0.

Used by

wp_get_attachment_image_srcset()

Usage Example
<?php
$image_meta = wp_get_attachment_metadata( 11 );
$image = wp_get_attachment_image_src( 11, 'medium' );
if ( $image ) {
	$image_src = $image[0];
	$size_array = array(
		absint( $image[1] ),
		absint( $image[2] )
	);
}
$srcset_value = wp_calculate_image_srcset( $size_array, $image_src, $image_meta );
$srcset = $srcset_value ? ' srcset="' . esc_attr( $srcset_value ) . '"' : '';
?>

<img src="myimg.png"<?php echo $srcset; ?> sizes="{{custom sizes value}}">
Note

By default, the maximum width of images that are included in the srcset is 1600 pixels. You can override this default by adding a filter to max_srcset_image_width.

 

Hook max_srcset_image_width

apply_filters( 'max_srcset_image_width', 1600, $size_array )

Filter the maximum image width to be included in a srcset attribute.

Parameters

$max_width (int) The maximum image width to be included in the srcset. Default ‘1600’.

$size_array (array) Array of width and height values in pixels (in that order).

Used by

wp_calculate_image_srcset()

Usage Example
<?php
// Increase the limit to 2048px if the image is wider than 800px.

function custom_max_srcset_image_width( $max_width, $size_array ) {
	$width = $size_array[0];

	if ( $width > 800 ) {
		$max_width = 2048;
	}

	return $max_width;
}
add_filter( 'max_srcset_image_width', 'custom_max_srcset_image_width', 10, 2 );

?>

Hook wp_calculate_image_srcset

apply_filters( 'wp_calculate_image_srcset', $sources, $size_array, $image_src, $image_meta, $attachment_id )

Filter an image’s srcset sources.

Parameters

$sources (array) One or more arrays of source data to include in the srcset.

$width (array) {
	$url (string)			The URL of an image source.
	$descriptor (string)	The descriptor type used in the image candidate string,
							either 'w' or 'x'.
	$value (int)			The source width, if paired with a 'w' descriptor or a
							pixel density value if paired with an 'x' descriptor.
}

$size_array (array) Array of width and height values in pixels (in that order).

$image_src (string) The src of the image.

$image_meta (array) The image meta data as returned by wp_get_attachment_metadata().

$attachment_id (int) Image attachment ID or 0.

Used by

wp_calculate_image_srcset()

Usage Example
<?php
// Remove sources wider than 800px from the 'srcset' for featured images.

function custom_wp_calculate_image_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id ) {
	if ( array_key_exists( 'post-thumbnail', $image_meta['sizes'] ) ) {
		$post_thumbnail_file = $image_meta['sizes']['post-thumbnail']['file'];
		$image_src_file = wp_basename( $image_src );

		if ( $image_src_file === $post_thumbnail_file ) {
			foreach ( $sources as $key => $source ) {
				if ( $source['value'] > 800 ) {
					unset( $sources[ $key ] );
				}
			}
		}
	}

	return $sources;
}
add_filter( 'wp_calculate_image_srcset', 'custom_wp_calculate_image_srcset', 10, 5 );

?>

Function wp_get_attachment_image_sizes

wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image_meta = null )

Retrieves the value for an image attachment’s sizes attribute.

Return: (string|bool) A valid source size value for use in a sizes attribute or false.

Parameters

$attachment_id (int) Image attachment ID.

$size (array|string) (Optional) Image size. Accepts any valid image size name (‘thumbnail’, ‘medium’, etc.), or an array of width and height values in pixels (in that order). Default ‘medium’.

$image_meta (array) (Optional) The image meta data as returned by wp_get_attachment_metadata(). Default null.

Uses

wp_calculate_image_sizes()

Usage Example
<?php
$sizes_value = wp_get_attachment_image_sizes( 11, 'medium' );
$sizes = $sizes_value ? ' sizes="' . esc_attr( $sizes_value ) . '"' : '';
?>

<img src="myimg.png"<?php echo $sizes; ?> srcset="{{custom srcset value}}">
Note

By default, the sizes attribute will be declared as 100% of the viewport width when the viewport width is smaller than the width of the image, or to the width of the image itself when the viewport is larger than the image:

(max-width: {{image-width}}) 100vw, {{image-width}}

You can override this default by adding a filter to wp_calculate_image_sizes.

Function wp_calculate_image_sizes

wp_calculate_image_sizes( $size, $image_src, $image_meta, $attachment_id = 0 )

Creates the sizes attribute value for an image.

Return: (string|bool) A valid source size value for use in a sizes attribute or false.

Parameters

$size (array|string) Image size. Accepts any valid image size name (‘thumbnail’, ‘medium’, etc.), or an array of width and height values in pixels (in that order).

$image_src (string) (Optional) The URL to the image file. Default null.

$image_meta (array) (Optional) The image meta data as returned by wp_get_attachment_metadata(). Default null.

$attachment_id (int) (Optional) Image attachment ID. Default 0.

Either $image_meta or $attachment_id is needed when using the image size name as argument for $size.

Used by

wp_get_attachment_image_sizes()

Usage Example
<?php
$sizes_value = wp_calculate_image_sizes( 'medium', $image_src = null, $image_meta = null, 11 );
$sizes = $sizes_value ? ' sizes="' . esc_attr( $sizes_value ) . '"' : '';
?>

<img src="myimg.png"<?php echo $sizes; ?> srcset="{{custom srcset value}}">
Note

By default, the sizes attribute will be declared as 100% of the viewport width when the viewport width is smaller than the width of the image, or to the width of the image itself when the viewport is larger than the image:

(max-width: {{image-width}}) 100vw, {{image-width}}

You can override this default by adding a filter to wp_calculate_image_sizes.

Hook wp_calculate_image_sizes

apply_filters( 'wp_calculate_image_sizes', $sizes, $size, $image_src, $image_meta, $attachment_id )

Filter the output of wp_calculate_image_sizes().

Parameters

$sizes (string) A source size value for use in a sizes attribute.

$size (array|string) Requested size. Image size name or array of width and height values in pixels (in that order).

$image_src (string|null) The URL to the image file or null.

$image_meta (array|null) The image meta data as returned by wp_get_attachment_metadata() or null.

$attachment_id (int) Image attachment ID of the original image or 0.

Used by

wp_calculate_image_sizes()

Usage Example
<?php
// Constrain the width of full size images to the content width.

function custom_wp_calculate_image_sizes( $sizes, $size, $image_src, $image_meta, $attachment_id ) {
	if ( is_array( $size ) ) {
		global $content_width;
		$width = $size[0]

		if ( $width > $content_width ) {
			$upload_dir = wp_upload_dir();
			$upload_baseurl = $upload_dir['baseurl'];
			$fullsize_file = $image_meta['file'];
			$fullsize_url = trailingslashit( $upload_baseurl ) . $fullsize_file;

			if ( $image_src === $fullsize_url ) {
				$sizes = '(max-width: ' . $content_width . 'px) 100vw, ' . $content_width . 'px';
			}
		}
	}

	return $sizes;
}
add_filter( 'wp_calculate_image_sizes', 'custom_wp_calculate_image_sizes', 10, 5 );

?>

Backward Compatibility

The following filters are used for backward compatibility. If the described case is not applicable you may want to remove the filter from its hook.

data-sizes

Prior to version 2.5 a srcset and data-sizes attribute were added to the image while inserting the image in the content and we used a content filter to replace data-sizes by sizes. As from 2.5 both srcset and sizes are added to images using a content filter, but images that already have a srcset attribute are skipped. For this reason we still replace data-sizes by sizes. If you did not use the plugin before version 2.5 or if you have removed data-sizes from your content you can remove the filter:

remove_filter( 'the_content', 'tevkori_replace_data_sizes' );

tevkori_get_sizes() $args param and filter

The deprecated function tevkori_get_sizes() had an $args param and a tevkori_image_sizes_args filter. To make those still work we added a shim. If you do not use tevkori_get_sizes() in your templates, or at least not pass an argument to the $args param, and if you don’t use the deprecated tevkori_image_sizes_args filter hook, you can remove the filter:

remove_filter( 'wp_calculate_image_sizes', '_tevkori_image_sizes_args_shim', 1, 5 );

wp_get_attachment_image_sizes filter

In version 3.0 we introduced a new filter: wp_get_attachment_image_sizes. In version 3.1 this has been replaced by wp_calculate_image_sizes. If you don’t use the wp_get_attachment_image_sizes filter you can remove the filter that has been added for backward compatibility:

remove_filter( 'wp_calculate_image_sizes', 'wp_get_attachment_image_sizes_filter_shim', 10, 5 );

Dependencies

The only external dependency included in this plugin is Picturefill – v3.0.1. If you would like to remove Picturefill (see notes about browser support), add the following to your functions.php file:

function mytheme_dequeue_scripts() {
  wp_dequeue_script('picturefill');
}

add_action('wp_enqueue_scripts', 'mytheme_dequeue_scripts');

We use a hook because if you attempt to dequeue a script before it’s enqueued, wp_dequeue_script has no effect. (If it’s still being loaded, you may need to specify a priority.)

Further reading

Leave a Reply