Don't go squishing my images

I haven’t done much with my website lately; apart from security updates, I’ve been too overwhelmed with work and life to write much this year. And what a year it’s been already! That’s not why I’m writing this post though.

I got the notification to update to WordPress 5.5 earlier this week, so I logged in, did the update, and glanced at a few pages to make sure everything worked okay. Usually it does, but this time, some of the images in my posts were looking pretty gnarly:

A quick element inspection showed me that WordPress was adding absolute pixel dimensions to all my images. I couldn’t even override it with CSS since it uses the width and height attributes on the image tag itself:

I think the absolute dimensions have been there for a while, but those attributes combined with my responsive layout and some block library CSS to make things look bad:

I tried a few different solutions to remove the width and height from my image tags before finding something that worked well. First, a post from CSS-Tricks (one of my favorite websites for advice on all things web design) suggested a couple of filters to use. Unfortunately, as I found out later, those filters only fire when an image is inserted into a post. The HTML is actually generated once and stored in the post instead of being generated dynamically as needed. I wanted to retroactively make this change for posts I’ve already published, and in particular I did not want to have to remove and re-insert images on old content.

I tried a few other filters including get_image_tag (yes, that page is for the function of the same name, but it’s also a filter which doesn’t seem to have its own page at the time of this writing) with the same result (that one also only fires on image insertion). Eventually, I found a Stack Exchange post that pointed me in the right direction.

My solution, roundabout as it is, is to modify all image tags in the the_content filter. That way, no matter when or how the markup was generated, my mini plugin will take out the width and height attributes, and the image will load with the right aspect ratio. I know there’s an argument for specifying the width and height so the browser knows how much space to reserve for the image, but that doesn’t make sense to me if it’s using the wrong height in the first place. I would rather make my pages load a little less smoothly in favor of my site rendering correctly when it does load. Plus, with well-optimized images, loading time is not really something I’m concerned about.

If you are curious how to reliably remove attributes from your images in WordPress, regardless of how long ago the posts they’re in were posted, here is my not-so-elegant solution to this very narrow niche of a problem:

function justincardoza_image_unsquisher($content)
{
    if(in_the_loop() && is_main_query())
    {
        $document = new DOMDocument();
        $document->loadHTML($content);
        $images = $document->getElementsByTagName('img');
        
        foreach($images as $image)
        {
            if($image->hasAttribute('width'))  $image->removeAttribute('width');
            if($image->hasAttribute('height')) $image->removeAttribute('height');
        }
        
        return $document->saveHTML();
    }
}

add_filter( 'the_content', 'justincardoza_image_unsquisher' );