Fluid Responsive Images in WordPress

Published: December 25, 2021

Right out of the box, WordPress does a nice job of making our images behave responsively, however it doesn’t give us complete control of image scaling behavior as the viewport width changes, fluidly. Following is a brief write–up describing how to gently bend WordPress and gain complete control over how your images scale responsively while using less yet more flexible code. I have tested this approach in WordPress version 5.8.2 with excellent results. This approach is non-destructive, lightweight, future proof and easily reversed if need be.

Requirements: You’ll need the ability to access and modify functions.php and style.css (both in the top level of your WordPress child or custom theme directory), the JavaScript associated with your WordPress child or custom theme and the ability to edit settings for an image block in your WordPress post editor. In this example I’m using jQuery however you can accomplish the same result with standard JavaScript.

Important Note: These modifications should only be made to a WordPress child theme or a custom WordPress theme. If you make these changes to a parent theme, there is a likelihood that the changes will be lost at some point in the future when you update your WordPress instance to a newer version. Making your modifications to a child or custom theme ensures they will persist.

The Rub: When we inspect the source of an image added to a post in WordPress (which I’ve expanded below in hopes of improving readability), we notice a few things. First, WordPress adds the srcset attribute to the img element. Second, WordPress adds a somewhat cryptic class (wp-image-298 in this example) to the img element. Third and finally, WordPress wraps the img element with a figure element.

As you can see, the srcset attribute adds a lot of markup intended to handle which image file is displayed at a set of particular viewport widths for responsiveness. This is all fine and dandy, however we can significantly simplify things and gain greater control of image responsiveness all at the same time by making a few modifications, which are outlined below.

<!-- expanded HTML associated with an image called My-Example-Image.png in a WordPress post -->
<figure class="wp-block-image size-large">
	<img 
		loading="lazy" 
		width="1024" 
		height="375" 
		src="https://www.brentpocker.com/thoughts/wp-content/uploads/2021/12/My-Example-Image-1024x375.png" 
		alt="My Example Image" 
		class="wp-image-298" 
		srcset="https://www.brentpocker.com/thoughts/wp-content/uploads/2021/12/My-Example-Image-1024x375.png 1024w, 
		https://www.brentpocker.com/thoughts/wp-content/uploads/2021/12/My-Example-Image-300x110.png 300w, 
		https://www.brentpocker.com/thoughts/wp-content/uploads/2021/12/My-Example-Image-768x281.png 768w, 
		https://www.brentpocker.com/thoughts/wp-content/uploads/2021/12/My-Example-Image-1536x563.png 1536w, 
		https://www.brentpocker.com/thoughts/wp-content/uploads/2021/12/My-Example-Image.png 2048w" 
		sizes="(max-width: 1024px) 100vw, 1024px"
	>
</figure>

Step 1: As a best practice, if you haven’t already, create a backup of your WordPress installation.

Step 2: Prevent WordPress from adding the srcset attribute to the post img element by adding the following function and filter to your functions.php page.

// prevent scrset attribute on img element
function disable_wp_responsive_images(){
	return 1;
}
add_filter('max_srcset_image_width', 'disable_wp_responsive_images');

Step 3: In the WordPress post editor, select your image block and expose the Advanced pane. In the Additional CSS class(es) field, add a CSS class name. This class name will be appended to the figure element and allow us to target the img element later in Step 5. I used a CSS class name of my-image-class for this example but any class name you like is perfectly fine.

Step 4: Remove the (somewhat cryptic) CSS class WordPress adds to your img element by adding the following jQuery statement to your jQuery document ready function.

// remove class attribute from WP managed post images
$('.my-image-class img').removeAttr('class');

Step 5: Replace my-image-class in the CSS rule below with the CSS class name you used in Step 3 and add the rule to your style.css file.

.my-image-class img {
	width: 100%;
	height: auto;
	background-position: center;
	background-size: contain;
}

Step 6: Lastly, clear your browser cache and refresh the webpage where your post lives. When you inspect the source, you’ll find the srcset attribute has not been added to the post img element, the CSS class attribute has been removed from the img element, your custom CSS class from Step 3 has been appended to the figure element and your CSS rule has been applied. Your source should look similar to the example below.

<figure class="wp-block-image size-large my-image-class">
	<img 
		loading="lazy" 
		width="1024" 
		height="375" 
		src="https://www.brentpocker.com/thoughts/wp-content/uploads/2021/12/My-Example-Image-1024x375.png" 
		alt="My Example Image" 
	>
</figure>

Going forward, to make any images you add to a post behave in the same delightful way, simply select the image block in the post editor, inspect the Advanced pane of the block settings inspector and add your custom CSS class from Step 3 to the Additional CSS class(es) field. Easy peasy!

Conclusion: You now have a responsive image which scales fluidly as the viewport width changes. In the process, you’ve made your HTML lighter-weight, improved the responsive behavior of your post image(s) and made the world a little bit better place. Enjoy!

Filed in — Web Development, WordPress Hacks

© 2024 Brent Pocker LLC. All rights reserved.