Img Src to Background-Image + object-fit:cover; polyfill for IE/Edge

This small JavaScript function converts the src attribute of an <img> tag into a CSS background-image, where 'background-size:cover;' can be applied effectively to make consistently sized images.

Works in modern browsers and IE9+. IE8 users will see the Figure 1 problem format below.

View the source of this page to see the HTML markup, CSS and JS.

The Problem

Images inserted into a web page via an <img> tag can be resized / scaled, but their sizing can be inconsistent (Figure 1).

Figure 1: Proportional scaling BUT inconsistent sizes when using <img> tags.

If we set a height and width to force size uniformity, the images get squished / stretched to fill the space (Figure 2).

Figure 2: Consistent sizes BUT distorted scaling when using <img> tags with explicit width and height.

The CSS3 object-fit property can fix the problem in Chrome, Firefox, Safari, and Opera, BUT, it isn't supported in IE or Edge!

A Workaround

We *could* switch to <div> tags instead, and use CSS to set each picture as a background-image, with 'background-size:cover;' to scale proportionally while we resize, BUT, this doesn't translate easily for use within a CMS. It would be great if we could somehow make 'background-size:cover;' work on <img> tags until IE/Edge supports object-fit...

A Solution

The fitImg(); JavaScript function demonstrated below, takes the URL from each image's src attribute and applies it as a CSS background-image instead, where 'background-size:cover;' can take effect via CSS. A transparent .gif (in data URI format) is set as the src to avoid broken image icons being displayed by the browser.

Note how the same image can be set to landscape or portrait, and 'background-size:cover;' will auto-fit it. Parts of the image that fall outside of the pre-defined placeholders will be cropped. Aspect ratio is maintained - no stretching or squishing.

I have structured the markup as a CMS would generate it (images are usually inserted inside a paragraph);

<p><img class="fit-img-landscape" src="pic-1.jpg" alt="" /><img class="fit-img-landscape" src="pic-2.jpg" alt="" /><img class="fit-img-landscape" src="pic-3.jpg" alt="" /></p>

But if you inspect one of the image elements with Developer Tools (F12), you'll see that the markup has been changed to;

<img class="fit-img-landscape" style="background-image:url(pic-1.jpg)" src="data:image/gif;base64,R...ICRAEAOw==" alt="" />

The fitImg(); function takes things one step further and makes use of the <p> wrappers within a CMS to overcome another problem - removing whitespace between inline-block elements by setting 'font-size:0;' on the parent element. If this doesn't suit your own setup, remove this line from the script;

img.parentNode.style.fontSize = '0'; /* counteract extra spacing from inline-block */

More demos and snippets

Did you find this useful? There are more demos and code snippets this way.