It often happens that the images in a design to be implemented have a specific format (1:1, 4:3, 16:9…) for a given screen width, but at another resolution their ratio changes. If the image is decorative, the best way to make it flexible is to use the background-size property with the values cover or contain. If the image is content, that solution no longer works — whether the image is injected through a CMS or written directly in the HTML document. So either we serve a different image for each screen width where the ratio changes, using the srcset attribute on the <img> tag, or we fit the one we have to the new format.

The old approach

Not that long ago, to achieve this effect we had to wrap the image in a container, give it the ratio we wanted, and place the image inside it with absolute positioning. That solved most cases, although every now and then an exception forced us to be more creative.

.image-wrapper { 
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
  position: relative;
}

.image-wrapper > img { 
  width: 100%; 
  height: auto; 
  position: absolute; 
  left: 0;
  top: 0; 
} 

Object-fit and Object-position

According to the W3C specification, the object-fit property defines how an image or video element will adapt its content to its container, and it can be combined with object-position, which determines where in the container the content will sit. These properties are similar to background-size and background-position.

object-fit can take the values: fill, contain, cover, none and scale-down

For the HTML tags <img> and <video>, we understand the container as the tag itself, and the content as the image or video linked through the src attribute.

  • Fill - Fits the content to its container without respecting its original ratio.
  • Contain - Resizes the content while keeping its ratio as it fits inside the container. The content may not fill the container, and the background colour will be visible.
  • Cover - Resizes the content while keeping its ratio and filling the container, although we may lose some of the image.
  • None - The content is not resized, so it is shown at its original size, without overflowing the size set by the container.
  • Scale-down - Compares the result of none and contain and picks the one that produces the smaller size.

In the demo you can see how each value of this property works.

Support

Support is quite broad, and we do not have to worry unless we still need to support Internet Explorer 11 :D

Conclusion

CSS is a language in constant evolution, and browsers implement new properties and specifications very quickly. Over the years, tasks get simpler because new properties help us solve and speed up more or less common jobs — but in return the language is broader, which makes it a bit harder to learn. That is part of evolution, and of life. CSS is growing up. Either way, we are celebrating because making a content image responsive — that is, adapting it to different resolutions — is easier than ever.