DEV Community

Ekaterina Vujasinović
Ekaterina Vujasinović

Posted on

How can object-fit property save you from misusing the background images

It's a very common situation - you have an image that needs to fit its content box without losing the aspect ratio. It seems that the easiest way to solve the problem is to insert your picture via CSS background-image and give it the background-size: cover property. There are also other background-* properties that can help you with positioning and styling.

However, inserting images with CSS is not always the most appropriate choice. It's how the purely decorative images should be handled. When it comes to the images that are providing any kind of meaningful information, 👉 object-fit gives us the ability to manipulate the content inside the <img> tag in a very similar way as background-size does with CSS-inserted background images.

TL;DR: Don't use background-* for images, videos or other replaced elements that are providing any kind of information, concepts or functionality. 👉 Use inline images and style them in CSS with object-fit and object-position instead.

For the sake of brevity, I will write mostly about handling images, instead referring to each kind of replaced elements separately. The main idea is the same, though.

Summary

👉 background-* vs object-fit
👉 Background images are not accessible
👉 Background images are not SEO-friendly
👉 Are there any performance issues with background images?
👉 Conclusion

Background vs object-fit

object-fit is used to fit image or video (and every other replaced element) to its content box. Images with non-decorative content should be inserted like this into the HTML document and further styled in the CSS stylesheet 👇

<!--index.html-->
<img src='meaningful-image.jpg' alt='this text describes the image' 
 class='.my-html-image'/>
Enter fullscreen mode Exit fullscreen mode
/*style.css*/
.my-html-image {
 object-fit: cover;
 object-position: left 10%, top 15%;
}
Enter fullscreen mode Exit fullscreen mode

Check the CodePen demo below for working example of object-fit values:

Decorative background images should be inserted like this into the CSS stylesheet 👇

/*style.css*/
.my-div {
    background-image: url(my-special-image-url.jpg);
    background-repeat: no-repeat;
    background-position: left 10% top 15%;
    background-size: cover;
}
Enter fullscreen mode Exit fullscreen mode

As you can see, it's not the amount or the complexity of code that makes a difference between those two ways of inserting images. The thing is that using background-* for non-decorative content have some serious drawbacks.

Background images are not accessible

Background images are meant to be purely decorative and it would be incorrect to make them "audible". It can be tempting to simply build a pie chart with conic gradient in CSS, but by doing it you are probably excluding people who cannot see the chart.

Screen readers and other assistive technologies rely on structural markup, and therefore, it is your responsibility as the developer to ensure that your HTML is semantically correct in describing the functional purpose of the content. Background images don't have a corresponding markup element - you set them in CSS directly - so, they are 'invisible' to the screen readers.

Besides proper HTML structure, there are other important accessibility features, like alt attributes for images, that cannot be used with background-* properties.

Browsers do not provide any special information on background images to assistive technology. This is important primarily for screen readers, as a screen reader will not announce its presence and therefore convey nothing to its users. 👉 If the image contains information critical to understanding the page's overall purpose, it is better to describe it semantically in the document.

-MDN, https://developer.mozilla.org/en-US/docs/Web/CSS/background

Background images are not SEO-friendly

Google parses the HTML of your pages to index images, but doesn't index CSS images. 👉 If you want your images to rank in Google Image search then you best use <img> tag with the src attribute pointing at the image. That said, it would be a shame to hide your visual content behind the background-image, especcially if it's a custom content that is additionally backing up your message.

As previously mentioned, background is purely CSS property and doesn't have a corresponding HTML tag or attributes. 👉 For good SEO results images should be placed near relevant text, have alt tags and maybe a caption - you can't do any of those with background-*.

Are there any performance issues with background images?

Yes, but there is hope on the horizon. There are some significant shortcomings regarding performance of background images:

👉 Background images are discovered by browser only after all CSS in page's <head> element has been downloaded and parsed. If there is a substantial amount of CSS, it may cause slower loading of the background image.

👉 Likewise, it is impossible to provide high-res images without writing a bunch of device pixel ratio media queries, which is a non-standard feature.

image-set() is a new feature that allows us to use different background images for different screen densities (just like srcset attribute in <img> tag) - hence solving the second problem. Even more so, image-set() can be used with the new preload feature 👇

The preload value of the <link> element's rel attribute lets you declare fetch requests in the HTML's <head>, specifying resources that your page will need very soon, which you want to start loading early in the page lifecycle, before browsers' main rendering machinery kicks in. 👉 This ensures they are available earlier and are less likely to block the page's render, improving performance.

- MDN, https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content

So, hopefully, if the browser support ever gets just a bit better for both image-set() and preload, we can consider both issues solved.

For more information, read this article on Google Developers.

Conclusion

Background images are not "bad" per se, they just have some shortcomings when implemented in the incorrect way. You should definitely choose them for abstract background pattern, background color / gradient, or some blurry, decorative image. But for your hero image or any other meaningful content, you might consider the <img> and <picture> tags, together with object-fit and object-position. The latter provides much more opportunities for accessible, easily discoverable and performant images.

Top comments (1)

Collapse
 
cezarytomczyk profile image
Cezary Tomczyk

Just a tip that images displayed through the CSS background property can be lazy loaded.