Skip to main content

Responsive images with picturefill in WordPress theme development

There is lots of talk about images in responsive web design. For some times I have used method of max-width:

.my-image {
   max-width: 100%;
   height: auto;
}

but generally I was not happy about it.
I have checked few solutions, and what I ended up using picturefill.
Here is how I integrated this in my development process:

Enqueue picturefill

First things first, enqueue ti WP way..

function vb_picturefill_enq() {
  wp_register_script('picturefill', get_template_directory_uri() . '/assets/js/picturefill.min.js', array('jquery'), null, false);
  wp_enqueue_script('picturefill');
}
add_action('wp_enqueue_scripts', 'vb_picturefill_enq', 100);

Adding support for picture tag

Second thing is adding support for picture tag, I will enqueue this in wp_head with add_action, per picturefill instructions:

function vb_picture_tag() { ?>
<script>
  document.createElement( "picture" );
</script>
<?php
}
add_action( 'wp_head', 'vb_picture_tag', 99 );

This is it, now I’m ready to use it in my theme.

Add image sizes

Next thing I do is create image sizes for different screen resolutions.
I use bootstrap framework so i use same naming convention just like for bootstrap brake points.
Because sm screen size and md screen size have almost exact width, I have chosen not to generate one more image size.

if ( function_exists( 'add_image_size' ) ) {
  add_image_size( 'featured-img-lg', 350, 185, true );
  add_image_size( 'featured-img-md', 285, 150, true );
  add_image_size( 'featured-img-xs', 690, 365, true );
}

XS is for screen size 0 – 768
MD is for screen size 768 – 1200
LG is for screen size 1200+

Displaying images

To make things a bit more simple I have created custom function which will automate a process for me and will replace standard function I use for getting images.
Function accepts 3 params, ID of the image, image size and alt attribute.

// Function for RWD images
function vb_rwd_image( $id, $size, $alt ) {
  $lg = wp_get_attachment_image_src( $id, $size.'-lg' );
  $md = wp_get_attachment_image_src( $id, $size.'-md' );
  $xs = wp_get_attachment_image_src( $id, $size.'-xs' );
?>
  <picture>
    <!--[if IE 9]><video style="display: none;"><![endif]-->
    <source srcset="<?php echo $lg['0']; ?>" media="(min-width: 1200px)">
    <source srcset="<?php echo $md['0']; ?>" media="(min-width: 768px)">
    <source srcset="<?php echo $xs['0']; ?>">
    <!--[if IE 9]></video><![endif]-->
    <img srcset="<?php echo $xs['0']; ?>" alt="<?php echo $alt; ?>">
  </picture>
<?php
}

Usage

Example usage in my theme file is:

vb_rwd_image( 11, 'featured-img', 'This is my alt text' );

Just not to confuse anyone, you can notice here how I created image size by name ‘featured-img-lg’ but I pass only ‘featured-img’ in my function.
This is because in function i concatenate size prefixes.

Function then generates following:

<picture>
    <!--[if IE 9]><video style="display: none;"><![endif]-->
    <source srcset="/myimage-350x185.jpg" media="(min-width: 1200px)">
    <source srcset="/myimage-285x150.jpg" media="(min-width: 768px)">
    <source srcset="/myimage-690x365.jpg">
    <!--[if IE 9]></video><![endif]-->
    <img srcset="/myimage-690x365.jpg" alt="This is my alt text">
</picture>

And that’s it. I must admit that life was simpler before this, and maybe I could use max-width and make it more simple, but I just want to do it right way. I believe there will be lots of changes about this in the future, so for now looks like I’m stuck with this.

Further reading

If you are interested for this subject further reading I would recommend few links:

2 comments

    1. Thanks.
      $my_image = get_field(‘my_image_id’);
      vb_rwd_image( $my_image, ‘featured-img’, ‘This is my alt text’ );

      All you need is to pass ID of your image in this function, get that first.

Leave a Reply

Your email address will not be published.

Please don’t paste any HTML, Js or PHP code into comments box, use pastebin.com or similar service to share code examples.

Characters left: 1000