Responsive Featured Image function in WordPress themes

Responsive Featured Images in WordPress

I really like including featured images when I am building WordPress themes. I almost feel like if they don’t have featured images for Posts and Pages it’s just not complete.

I also build all of the themes to work responsively. So if a user uploads a massive featured image this can be a problem. We don’t want to load a huge image in a mobile device. In the spirit of keeping our load times down I have been experimenting with a function that you can use in your themes that progressively loads the featured image using media queries.

First step is to make sure that your theme supports post thumbnails:

add_theme_support( 'post-thumbnails' );

The following function is pretty simple. What is does is get the post thumbnail id using the post ID, retrieve the various image sizes associated with that image file and then display those images based on viewport size.

So we start by creating our function. This will go in our functions.php file of our theme:


function my_featured_image() {

	// call the global post variable
	global $post;

	// get the post thumbnail ID for the page or post
	$post_thumbnail_id = get_post_thumbnail_id( $post->ID );

} // end function my_featured_image

add_action( 'wp_head', 'my_featured_image' );

In the example above we get the featured image id using the get_post_thumbnail_id and the post variable. We store the featured image id in the $post_thumbnail_id variable. We are also adding the outputted CSS to our header which will render our styles using the action wp_head. Since this will output the styles site wide on the front end we may want to wrap the function with a conditional statement. But we’ll get to that …

Next we will grab the image sizes for the featured image.

	// store the image sizes in an array
	$img_sizes = array( 'thumbnail', 'medium', 'large', 'full' );

This grabs the default image sizes already allocated by WordPress. You could add your own image sizes in this array using the add_image_size function.

Next we will grab the URL’s for each image size.

	// grab the URL for each image size and store in a variable
	foreach ( $img_sizes as $img_size ) {
		${ 'img_src_' . $img_size } = wp_get_attachment_image_src( $post_thumbnail_id, $img_size );
	}

Next we need to add our styles. We will be using CSS to call our image as a background-image. Therefore we must specify a width and height in order for the CSS element to show on the font end.

We will be using a bit of CSS3 to make this work. Lets call our class we will apply to our element for use in our markup

	echo '<style type="text/css">

		.featured-image {

			width: 100%; 		/* add a width to your image. 100% will fill the container */
			min-height:350px; 	/* Add the desired height of your element */

			background-image: url(' . esc_url( $img_src_thumbnail[0] ) . '); /* Call the thumbnail image for small screens first */
			-webkit-background-size: cover;
			-moz-background-size: cover;
			background-size: cover; 			/* CSS3 property used to make an image fill its container. You could also use contain or nothing at all */
			background-repeat: no-repeat;
			background-position: center center; /* center our image */
		}

	</style>';

Not too original but it will work!

Lets add our media queries now. I am using some standard widths here but you will want to tailor these to your theme and presentation. 

		@media screen and ( min-width: 600px ) and ( max-width:768px ) {
			.featured-image {
				background-image: url(' . esc_url( $img_src_medium[0] ) . ');
			}
		}

		@media screen and ( min-width: 768px ) and ( max-width:1200px ) {
			.featured-image {
				background-image: url(' . esc_url( $img_src_large[0] ) . ');
			}
		}

		@media screen and ( min-width: 1200px ) {
			.featured-image {
				background-image: url(' . esc_url( $img_src_full[0] ) . ');
			}
		}

We must place a conditional within the function to output the code only if the post or page has a featured image so lets wrap our function in a with an if statement. To do this we will use the has_post_thumbnail function. Putting it all together we get the following function:


/**
 * Responsive Featured Image Background
 *
 * @link http://s2webpress.com//responsive-featured-image-function-in-wordpress-themes/
 * @author Steven Slack
 *
 */
 
function my_featured_image() {

    // call the global post variable
    global $post;
 
    if ( has_post_thumbnail( $post->ID ) ) : // checks whether the post has the featured image set
         
    // get the post thumbnail ID for the page or post
    $post_thumbnail_id = get_post_thumbnail_id( $post->ID );
     
    // store the image sizes in an array. You can also add your own image sizes with the add_image_size function
    $img_sizes = array( 'thumbnail', 'medium', 'large', 'full' );
 
    // grab the URL for each image size and store in a variable
    foreach ( $img_sizes as $img_size ) {
        ${ 'img_src_' . $img_size } = wp_get_attachment_image_src( $post_thumbnail_id, $img_size );
    }
     
    echo '<style type="text/css"> 
 
        .featured-image {
 
            width: 100%;        /* add a width to your image. 100% will fill the container */
            min-height:350px;   /* Add the desired height of your element */
 
            background-image: url(' . esc_url( $img_src_thumbnail[0] ) . '); /* Call the thumbnail image for small screens first */
            -webkit-background-size: cover;
            -moz-background-size: cover;
            background-size: cover;             /* CSS3 property used to make an image fill its container. You could also use contain or nothing at all */
            background-repeat: no-repeat;
            background-position: center center; /* center our image */
        }
 
        @media screen and ( min-width: 600px ) and ( max-width:768px ) {
            .featured-image {
                background-image: url(' . esc_url( $img_src_medium[0] ) . ');
            }
        }
 
        @media screen and ( min-width: 768px ) and ( max-width:1200px ) {
            .featured-image {
                background-image: url(' . esc_url( $img_src_large[0] ) . ');
            }               
        }
 
        @media screen and ( min-width: 1200px ) {
            .featured-image {
                background-image: url(' . esc_url( $img_src_full[0] ) . ');
            }               
        }
 
    </style>';
 
   endif; // end if the featured image is set
 
} // end function my_featured_image
 
add_action( 'wp_head', 'my_featured_image' );

To add the featured image to the front end of our site we will first create a function below our function above which will create the necessary markup only if the post or page has a featured image.

/**
 * Return the featured image
 * @return html string 
 */
function the_featured_image_output() {

	global $post;

	if( has_post_thumbnail( $post->ID ) ) :
 
    // The Posts featured image title attribute
    $title_attr = get_post( get_post_thumbnail_id() )->post_title; //The Post Title
     
	$featured_img = '<div class="featured-image" role="img" aria-label="' . $title_attr . '"></div>';

	return $featured_img;

	endif;
}

Here again we are using the has_post_thumbnail function to check whether the current post has a featured image. If no image is set then the markup will not be returned.

Now you can place the function inside your theme where you would like the image to show up.

<?php echo the_featured_image_output(); ?>

This could be used in many different ways as well. I like to use them for big featured images at the tops of pages. It could even be used as a main image on your front page. You can also add in your custom styles markup as well such as overlaying the title on top of the image.

Remember that you may want to check your image sizes in Settings->Media or add your own sizes to the $img_sizes array.

17 thoughts on “Responsive Featured Image function in WordPress themes

  1. Thanks for posting this! It was exactly what I was trying to do, but I don’t quite have the PHP chops to code it all myself yet.

  2. I found this post very helpful Steven and it put me on the right path, but I am having some trouble with delivering the actual image. The media queries and breakpoints are working, but the source URL is nowhere to be found in the CSS background-image style.

        • Do you have a featured image set for that post or page? I think that is your issue. I have updated the article with a more appropriate conditional checking whether the post or page has a featured image set. I have replaced line 13 where it reads:
          if ( is_home() ) :
          with this:
          if ( has_post_thumbnail( $post->ID ) ) :

          Check out the updated code above.

          • Yes, I have a featured image set for that post. I understand the updates as well, I modified those lines earlier actually. :) Thank you. Now with the new “the_featured_image_output” function I can’t get the image to appear at all, let alone the source URL. I am simply trying to apply the featured image to several custom queries i.e.

            $args = array(
            ‘cat’ => ‘-10′,
            ‘post_type’ => ‘casestudy’,
            ‘posts_per_page’ => 1
            );
            $query = new WP_Query( $args );

            I want to eliminate the thumbnail function for your responsive solution. I appreciate the help.

          • The custom query shouldn’t matter. The function the_featured_image_output() is made to only output the code if the featured image is set. This may be why you are not seeing anything now. But, since you said you had the featured image set I am not really sure what is happening. If you fill out my contact form and provide some FTP credentials I’d be happy to take a look.

  3. Hello there,
    I’m new to this but I followed the instructions and I would like to include the
    “” within a loop to show the thumbnails of each post.
    Is there anything i need to change in functions.php?
    Regards

    • You can just include the snippet < ?php echo the_featured_image_output(); ?> in the loop and as long as the the_featured_image_output function is in your functions.php file along the the my_featured_image function everything should work. :)

      • Hey steven thanks for the reply,
        I’ve included everything in the functions.php and placed inside the loop of . But for some odd reason all the posts are appearing with the same thumbnails. (correct links to the posts just the thumbnails are the same)
        Is there something I’m missing? Maybe clashing with something?
        Regards and thanks again for the response

        • Hey steven thanks for the reply,
          I’ve included everything in the functions.php and placed: php echo the_featured_image_output() inside the loop of: ? php while (have_posts()) : the_post(); ? >. But for some reason all the posts are appearing with the same thumbnails. (correct links to the posts just the thumbnails are the same)
          Is there something I’m missing? Maybe clashing with something?
          Regards and thanks again for the response

          • I created this for use on single post pages. I haven’t written a function for the blog loop. But it seems that if it was used in the same way it would output too many styles in the header. I recommend just using it for your single posts and pages.

  4. Hey steven thanks for the reply,
    I’ve included everything in the functions.php and placed: php echo the_featured_image_output() inside the loop of: ? php while (have_posts()) : the_post(); ? >. But for some reason all the posts are appearing with the same thumbnails. (correct links to the posts just the thumbnails are the same)
    Is there something I’m missing? Maybe clashing with something?
    Regards and thanks again for the response

  5. You saved my life, dude! I just needed some quick help to finish my job before the end of the day and thanks to your post it took me only a few minutes to do it instead of a lethal work! Thank you!

Leave a Reply