Responsify WP is the WordPress plugin that cares about responsive images.
- Use
img
with srcset/sizes attributes. - ...or the
picture
element. - Works with or without Picturefill.
- Supports high resolution images (retina).
- Custom media queries.
- Handpick which image sizes to use.
- Responsive background images.
Basic demonstration
https://www.youtube.com/watch?v=3ThYWO6vHKI
Demo site
http://responsifywp.com/demo/
In short, it will replace all <img>
tags within the_content
(or other filters that you can add yourself) with responsive images.
For example, you might have a template that looks like this:
<article>
<h1><?php the_title();?></h1>
<?php the_content();?>
</article>
This might output something like this:
<article>
<h1>Hello world</h1>
<p>Lorem ipsum dolor sit amet...</p>
<img src="full-size.jpg" alt="Image description">
</article>
But once you have activated the plugin, it will look like this instead:
<article>
<h1>Hello world</h1>
<p>Lorem ipsum dolor sit amet...</p>
<img sizes="(min-width: 1024px) 1440px, (min-width: 300px) 1024px, (min-width: 150px) 300px, 150px"
srcset="thumbnail.jpg 150w,
medium.jpg 300w,
large.jpg 1024w,
full-size.jpg 1440w"
alt="Image description">
</article>
On the RWP settings page, you can select between using an <img>
tag with sizes
/srcset
attributes and the <picture>
element.
<picture>
<source srcset="full-size.jpg" media="(min-width: 1024px)">
<source srcset="large.jpg" media="(min-width: 300px)">
<source srcset="medium.jpg" media="(min-width: 150px)">
<img srcset="thumbnail.jpg" alt="Image description">
</picture>
Congratulations! You're now serving images with an appropriate size to the users.
The different versions of the image in the examples above is in the standard thumbnail
, medium
, large
and full
sizes.
Any custom sizes of the image will also be found and used.
The media queries that the picture
element are using is based on the width of the "previous" image.
RWP also has support for the old markup pattern that uses <span>
tags. However, this solution has some
limitations and is not the recommended.
<span data-picture data-alt="Image description">
<span data-src="thumbnail.jpg"></span>
<span data-src="medium.jpg" data-media="(min-width: 150px)"></span>
<span data-src="large.jpg" data-media="(min-width: 300px)"></span>
<span data-src="full-size.jpg" data-media="(min-width: 1024px)"></span>
<noscript>
<img src="thumbnail.jpg" alt="Image description">
</noscript>
</span>
You can select which image sizes that the plugin should use from the settings page.
These settings can be overwritten from your templates.
<?php
// Using get_posts()
$posts = get_posts( array(
'post_type' => 'portfolio',
'rwp_settings' => array(
'sizes' => array('large', 'full')
)
) );
foreach( $posts as $post ) {
// ...
}
// Using WP_Query()
$query = new WP_Query( array(
'category_name' => 'wordpress',
'rwp_settings' => array(
'sizes' => array('large', 'full')
)
) );
if ( $query->have_posts() ) {
// ...
}
?>
By default, <img>
tags with sizes
/srcset
is the selected markup pattern. You can override the calculated value of the sizes
attribute by doing this:
<?php
$posts = get_posts(array(
'post_type' => 'portfolio',
'rwp_settings' => array(
'sizes' => array('medium', 'large'),
'attributes' => array(
'sizes' => '(min-width: 500px) 1024px, 300px'
)
)
));
?>
This will produce the following:
<img srcset="medium.jpg 300w, large.jpg 1024w" sizes="(min-width: 500px) 1024px, 300px)" src="medium.jpg">
large.jpg
will be selected when the window width is at least 500px. On smaller screens, medium.jpg
will be selected.
If you've selected the picture
element in the settings, you can specify your own media queries for the different image sizes.
<?php
$posts = get_posts(array(
'post_type' => 'portfolio',
'rwp_settings' => array(
'sizes' => array('thumbnail', 'medium', 'large'),
'media_queries' => array(
'medium' => 'min-width: 500px',
'large' => 'min-width: 1024px'
)
)
));
?>
In the example above, thumbnail
is the smallest image size and should therefore have no media query specified.
medium
will be selected if the screen is 500 px or larger. The same goes for large
if the screen is at least 1024 px.
<picture>
<source srcset="large.jpg" media="(min-width: 1024px)">
<source srcset="medium.jpg" media="(min-width: 500px)">
<img srcset="thumbnail.jpg" alt="Image description">
</picture>
On the RWP settings page, you can choose if high resolution (retina) images should be used or not. This can be overwritten
by setting retina
to either true
or false
in the rwp_settings
array.
If set to true
, RWP will use all images that has the @[value]x
suffix in the name, like thumbnail@2x
or
[email protected]
.
<?php
$posts = get_posts(array(
'rwp_settings' => array(
'retina' => true // or false
)
));
?>
In this example, the three image sizes has a retina version which is twice the size.
<picture>
<source srcset="full.jpg" media="(min-width: 1024px)">
<source srcset="large.jpg, large_retina.jpg 2x" media="(min-width: 300px)">
<source srcset="medium.jpg, medium_retina.jpg 2x" media="(min-width: 150px)">
<source srcset="thumbnail.jpg, thumbnail_retina.jpg 2x">
<img srcset="thumbnail.jpg" alt="Image description">
</picture>
You can also add image sizes for other pixel densities, like 1.5x
or 3x
. This is the same example that also has a
retina version that's three times as large.
<picture>
<source srcset="full.jpg" media="(min-width: 1024px)">
<source srcset="large.jpg, large_retina.jpg 2x, large_retina_xl.jpg 3x" media="(min-width: 300px)">
<source srcset="medium.jpg, medium_retina.jpg 2x, medium_retina_xl.jpg 3x" media="(min-width: 150px)">
<source srcset="thumbnail.jpg, thumbnail_retina.jpg 2x, thumbnail_retina_xl.jpg 3x">
<img srcset="thumbnail.jpg" alt="Image description">
</picture>
You can select which versions that you wanna use by default on the RWP settings page. This can also be overwritten by passing
an array of pixel densities to rwp_settings
.
<?php
$posts = get_posts(array(
'rwp_settings' => array(
'retina' => array( '1.5x', '2x' )
)
));
?>
For a single density, you can of course pass it as a string.
<?php
'rwp_settings' => array(
'retina' => '2x'
)
?>
A new feature in Responsify WP 1.7 is the support for high resolution (retina) images. This means that devices with
high pixel density screens will receive larger images which will look crisp and sharp.
However, larger images means heavier images, which is something RWP is meant to prevent. With that said, this is how
the generated markup looks like:
<!-- Picture element -->
<picture>
<source srcset="large.jpg, large_retina.jpg 2x" media="(min-width: 300px)">
<source srcset="medium.jpg, medium_retina.jpg 2x" media="(min-width: 150px)">
<img srcset="thumbnail.jpg" alt="Image description">
</picture>
<!-- img with srcset/sizes -->
<img srcset="
thumbnail.jpg 150w,
medium.jpg 300w,
medium_retina.jpg 600w,
large.jpg 1024w,
large_retina.jpg 2048w"
sizes="(min-width: 300px) 1024px, (min-width: 150px) 300px, 150px">
If you want to use retina images, they has to be generated first. This requires you to manually add custom image sizes
using the add_image_size
function.
Let's use the three default image sizes that ships with WordPress and their default settings as an example:
thumbnail
150x150pxmedium
300x300pxlarge
1024x1024px
If you want to create retina versions of these image sizes, you should add something like this to your functions.php
:
<?php
add_image_size( 'medium@2x', 600, 600 );
add_image_size( 'large@2x', 2048, 2048 );
?>
As you can see, the @2x
suffix indicates that medium@2x
is twice as large as medium
for example.
There's no thumbnail@2x
since that would be the same as medium
.
Images that are uploaded to WordPress from now on will be generated in these sizes. If you want to create retina versions
of existing images, use the Regenerate thumbnails plugin.
RWP works with other pixel densities beside of 2x
as well. 1.5x
or 3x
will also work just fine. The important thing
is that you name your custom image sizes like this:
[original]@[value]x`
Add 1.5x
and 2x
versions of the default image sizes:
<?php
add_image_size( '[email protected]', 225, 225 );
add_image_size( '[email protected]', 450, 450 );
add_image_size( 'medium@2x', 600, 600 );
add_image_size( 'large@2x', 2048, 2048 );
?>
It of course works with other custom sizes as well!
<?php
add_image_size( 'tablet-landscape', 800, 600 );
add_image_size( 'tablet-landscape@2x', 1600, 1200 );
add_image_size( 'tablet-landscape@3x', 2400, 1800 );
?>
thumbnail
, medium
and large
will work as usual:
<!-- Picture element -->
<picture>
<source srcset="large.jpg" media="(min-width: 800px)">
<source srcset="tablet_landscape.jpg, [email protected] 2x, [email protected] 3x" media="(min-width: 150px)">
<source srcset="medium.jpg" media="(min-width: 150px)">
<img srcset="thumbnail.jpg" alt="Image description">
</picture>
<!-- img with srcset/sizes -->
<img srcset="
thumbnail.jpg 150w,
medium.jpg 300w,
tablet_landscape.jpg 800w,
[email protected] 1600w,
[email protected] 2400w,
large.jpg 1024w,"
sizes="(min-width: 800px) 1024px, (min-width: 300px) 800px, (min-width: 150px) 300px, 150px">
RWP provides a number of functions that can generate responsive images in your templates.
Based on an attachment ID, you can generate either a picture element or a img tag with srcset
/sizes
attributes.
<?php echo rwp_img( $attachment_id ); ?>
<?php echo rwp_picture( $attachment_id ); ?>
Let's say that you have the following markup for a very large header image:
<header>
<?php the_post_thumbnail( 'full' ); ?>
</header>
As you probably know, the_post_thumbnail()
will just create a regular <img>
tag for the full-size image in this case.
But you does of course not want to send a big 1440px image to a mobile device. This can easily be solved like this:
<header>
<?php
$thumbnail_id = get_post_thumbnail_id( $post->ID );
echo rwp_picture( $thumbnail_id );
?>
</header>
You can also specify which sizes of the image that should be used:
<?php
$thumbnail_id = get_post_thumbnail_id( $post->ID );
echo rwp_picture( $thumbnail_id, array(
'sizes' => array( 'medium', 'large', 'full' )
) );
?>
There might be times when you have a div
with a very large background image. It's very easy to replace the image with a smaller one using media queries in your stylesheet, but that requires you to hard code the filename.
What if it's some kind of header image that can be changed later by the administrator of the site? In that case, you cannot hard code the filename inside your stylesheet.
You might have done something like this in the past:
<header id="hero" style="background-image: url(<?php echo $dynamic_header_image;?>)">
<h1>Overlying headline</h1>
</header>
Instead, you could do this:
<?php
echo rwp_style( $dynamic_header_image_ID, array(
'selector' => '#hero'
) );
?>
<header id="hero">
<h1>Overlying headline</h1>
</header>
This will generate a style
tag containing the following:
#hero {
background-image: url("thumbnail.jpg");
}
@media screen and (min-width: 150px) {
#hero {
background-image: url("medium.jpg");
}
}
// And so on...
You can of course specify sizes and media queries here to.
<?php
echo rwp_style( $dynamic_header_image_ID, array(
'selector' => '#hero',
'sizes' => array('medium', 'large', 'full'),
'media_queries' => array(
'large' => 'min-width: 500px',
'full' => 'min-width: 1024px'
)
) );
?>
The rwp_attributes()
function returns an array of attributes for the selected element. This might be
useful if you for example want to create the elements later with Javascript.
<?php
$img_attributes = rwp_attributes( $attachment_id, array(
'element' => 'img'
) );
// $img_attributes equals this:
$img_attributes = array(
'srcset' => 'thumbnail.jpg 150w, medium.jpg 300w, large.jpg 1024w',
'sizes' => '(min-width: 300px) 1024px (min-width: 150px) 300px, 150px'
);
?>
It of course works with the picture element to:
<?php
$picture_attributes = rwp_attributes( $attachment_id, array(
'element' => 'picture'
) );
// $picture_attributes equals this:
$picture_attributes = array(
'source' => array(
array(
'srcset' => 'large.jpg',
'media' => '(min-width: 300px)'
),
array(
'srcset' => 'medium.jpg',
'media' => '(min-width: 150px)'
),
),
'img' => array(
'srcset' => 'thumbnail.jpg'
)
);
?>
It is also possible to pass custom settings to the function.
<?php
$picture_attributes = rwp_attributes( $attachment_id, array(
'element' => 'picture',
'sizes' => array('thumbnail', 'medium'),
'media_queries' => array(
'medium' => 'min-width: 1024px'
)
) );
// $picture_attributes equals this:
$picture_attributes = array(
'source' => array(
array(
'srcset' => 'medium.jpg',
'media' => '(min-width: 1024px)'
)
),
'img' => array(
'srcset' => 'thumbnail.jpg'
)
);
?>
RWP is providing the following functions:
rwp_img( $attachment_id, $settings )
rwp_picture( $attachment_id, $settings )
rwp_span( $attachment_id, $settings )
rwp_attributes( $attachment_id, $settings )
rwp_style( $attachment_id, $settings )
These are the settings that is currently avaliable:
- sizes (array): The image sizes that you want to use.
- media_queries (array): An associative array of names of the image sizes and a custom media query.
- attributes (array): An associative array of attribute names and values that you want to add on the element (see example).
- retina (bool|string|array): True/false. String or array of pixel densities (x descriptor).
- ignored_image_formats (array): An array of image formats that you want RWP to ignore.
<?php
$settings = array(
'sizes' => array('medium', 'large')
);
echo rwp_img( $attachment_id, $settings );
echo rwp_picture( $attachment_id, $settings );
?>
<img sizes="(min-width: 300px) 1024px, 300px"
srcset="large.jpg 1024w,
medium.jpg 300w"
alt="Image description">
<picture>
<source srcset="large.jpg" media="(min-width: 300px)">
<img srcset="medium.jpg" alt="Image description">
</picture>
<?php
$settings = array(
'sizes' => array('thumbnail', 'medium', 'large'),
'media_queries' => array(
'medium' => 'min-width: 500px',
'large' => 'min-width: 1024px'
)
);
echo rwp_picture( $attachment_id, $settings );
?>
Notice that you should not specify a media query for the smallest image size. You must specify a media query for all the selected image sizes.
<picture>
<source srcset="large.jpg" media="(min-width: 1024px)">
<source srcset="medium.jpg" media="(min-width: 500px)">
<img srcset="thumbnail.jpg" alt="Image description">
</picture>
<?php
$settings = array(
'attributes' => array(
'id' => 'responsive-image',
'sizes' => '(min-width: 500px) 1024px, 300px'
)
);
echo rwp_img( $attachment_id, $settings );
?>
<img id="responsive-image" sizes="(min-width: 500px) 1024px, 300px"
srcset="thumbnail.jpg 150w,
medium.jpg 300w,
large.jpg 1024w,
full-size.jpg 1440w"
alt="Image description">
<?php
$settings = array(
'attributes' => array(
'picture' => array(
'id' => 'picture-element'
),
'source' => array(
'data-foo' => 'bar'
),
'img' => array(
'id' => 'responsive-image'
)
)
);
echo rwp_picture( $attachment_id, $settings );
?>
<picture id="picture-element">
<source data-foo="bar" srcset="full-size.jpg" media="(min-width: 1024px)">
<source data-foo="bar" srcset="large.jpg" media="(min-width: 300px)">
<source data-foo="bar" srcset="medium.jpg" media="(min-width: 150px)">
<img id="responsive-image" srcset="thumbnail.jpg" alt="Image description">
</picture>
<?php
$settings = array(
'attributes' => array(
'picture_span' => array(
'id' => 'picture-element',
'data-alt' => 'Overrides the alternative text of the image'
),
'src_span' => array(
'class' => 'responsive-image'
)
)
);
echo rwp_picture( $attachment_id, $settings );
?>
<span data-picture id="picture-element" data-alt="Overrides the alternative text of the image">
<span class="responsive-image" data-src="thumbnail.jpg"></span>
<span class="responsive-image" data-src="medium.jpg" data-media="(min-width: 150px)"></span>
<span class="responsive-image" data-src="large.jpg" data-media="(min-width: 300px)"></span>
<span class="responsive-image" data-src="full-size.jpg" data-media="(min-width: 1024px)"></span>
<noscript>
<img src="thumbnail.jpg" alt="Image description">
</noscript>
</span>
The rwp_edit_generated_element
filter allows you to edit and modify the generated element before it's inserted back into the content.
<?php
function edit_responsive_image( $element ) {
// Do something with $element
return $element;
}
add_filter( 'rwp_edit_generated_element', 'edit_responsive_image' );
?>
One use case might be replacing the srcset
attribute with data-srcset
for implementing some kind of lazy load solution.
<?php
function replace_srcset_with_data_srcset( $element ) {
$element = str_replace('srcset', 'data-srcset', $element);
return $element;
}
add_filter( 'rwp_edit_generated_element', 'replace_srcset_with_data_srcset' );
?>
The rwp_edit_attributes
filter allows you to edit the attributes of the generated element.
<?php
function edit_attributes( $attributes ) {
// Do something with $attributes...
return $attributes;
}
add_filter( 'rwp_edit_attributes', 'edit_attributes' );
?>
Example
<!-- Original image -->
<img src="large.jpg" class="size-large" alt="My image">
<?php
function edit_attributes( $attributes ) {
// $attributes equals this:
// $attributes = array(
// 'sizes' => '(min-width: 300px) 1024px, (min-width: 150px) 300px, 150px',
// 'class' => 'size-large',
// 'alt' => 'My image'
// );
return $attributes;
}
add_filter( 'rwp_edit_attributes', 'edit_attributes' );
?>
This can be useful if you for example want to edit the sizes
attribute in specific situations.
The following example overrides the generated sizes
attribute when the original image has the size-large
class.
<?php
function edit_attributes( $attributes ) {
if ( is_integer( strpos( $attributes['class'], 'size-large') ) ) {
$attributes['sizes'] = '(min-width: 500px) 1024px, (min-width: 300px) 300px, 150px';
}
return $attributes;
}
add_filter( 'rwp_edit_attributes', 'edit_attributes' );
?>
The rwp_add_filters
filter allows you to add additional filters (confusing, I know) that RWP
should be applied on.
RWP is by default applied to the post_thumbnail_html
and the_content
filters. Any images found inside
these filters will be made responsive.
<?php
function add_filters( $filters ) {
$filters[] = 'my_custom_filter';
return $filters; // Equals array( 'the_content', 'post_thumbnail_html', 'my_custom_filter' )
}
add_filter( 'rwp_add_filters', 'add_filters' );
?>
There might be times when you simply don't want RWP to do anything with an image. This can be achived by adding the
rwp-not-responsive
class to the image.