Picturefill.js + WordPress

Matt Marquis, chair of the Responsive Images Community Group, asked on Twitter:

Anyone know whether picture/Picturefill support is officially in the works for WordPress? Could swear I saw something about that once.

There’s no official, native support for the <picture> element (or its polyfill) in WordPress, and the Picturefill.js script is not included in the WordPress distribution (like jQuery is), but you can use both the <picture> element along with Picturefill.js in your WordPress theme today, if you’re not afraid of a little custom theming. We’ll follow the instructions for using Picturefill.js by Scott Jehl for our actual <picture> element markup.

First, Establish Your Image Sizes

Consider this screenshot from a recent WordPress project we launched at RP3 Agency:

Long & Foster Newsroom
Long & Foster Newsroom

These featured images change size responsively with the viewport. First off, there’s no getting around simple CSS scaling. As inefficient as it might be, you’re just not going to cut an image for each conceivable viewport. What I aimed for is finding my breakpoints, and then determining the largest size the image would be just before the breakpoint caused the design to shift:

Long & Foster Newsroom at 400 pixels wide
Long & Foster Newsroom at 400 pixels wide

The main breakpoint for this section is 572 pixels wide. Additionally, I want to cut images for the 320 pixel wide viewport. So that’s three breakpoints, essentially. So I add three image sizes accordingly in my functions.php file:

add_image_size( 'home_feature_block_narrow', 295, 288, true );
add_image_size( 'home_feature_block_medium', 539, 526, true );
add_image_size( 'home_feature_block_wide', 438, 457, true );

Second, Build Your Picture Element

Next, we use the image sizes to build our <picture> element in our theme’s template:

if ( get_the_post_thumbnail() != '' ):
    $image_small  = wp_get_attachment_image_src( get_post_thumbnail_id(), 'home_feature_block_narrow' );
    $image_medium = wp_get_attachment_image_src( get_post_thumbnail_id(), 'home_feature_block_medium' );
    $image_large  = wp_get_attachment_image_src( get_post_thumbnail_id(), 'home_feature_block_wide' );

    <!--[if IE 9]><video style="display: none;"><![endif]-->
    <source srcset="<?php echo esc_url( $image_large[0] ); ?>" media="(min-width: 572px)">
    <source srcset="<?php echo esc_url( $image_medium[0] ); ?>" media="(min-width: 321px)">
    <source srcset="<?php echo esc_url( $image_small[0] ); ?>"></span>
    <!--[if IE 9]></video><![endif]-->
    <img srcset="<?php echo esc_url( $image_small[0] ); ?>">

<?php endif; ?>

Last, Enqueue Your Polyfill

Now, make sure you’re adding Picturefill.js version 2 with the wp_enqueue_script function in functions.php (after you download and install it in your WordPress theme directory):

function enqueue_picturefill() {
    wp_enqueue_script( 'picturefill', get_template_directory_uri() . '/js/picturefill.min.js', array(), '20140520', false );
add_action( 'wp_enqueue_scripts', 'enqueue_picturefill' );

VoilĂ ! The <picture> element, Picturefill.js, and WordPress in one, nice package. Now go forth, and responsify!

You can see more responsive WordPress tips and tricks in my slides from my WordCamp Miami talk at http://taupecat.github.io/responsify.

(This post has been edited to remove a custom function.)

2 thoughts on “Picturefill.js + WordPress

  1. Hi there,

    Interesting blogpost, because I’m looking for a solid solution for this. It’s about time I implement picturefill in my project.

    When I try to implement your solution I get this error, though:
    Fatal error: Call to undefined function lfn_get_attachment() in /Users/bramwillemse/Dropbox/Sites/gsc/content/themes/goldmine/inc/headerimg.php on line 8

    I guess this is a custom function. If you could share the function too, that’d help understand it (and implement it) quickly.

    Thanks for sharing!

    1. Yeah, that is a custom function. I’ll update the post as soon as I get a chance so that error won’t happen. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *