This post was originally published at Exploring object-fit

On web documents, a common problem concerns the display of different sized images (or videos) in the same place. Perhaps you are writing a dynamic gallery app that accepts user submissions. You can’t guarantee that everyone will upload images of exactly the same aspect ratio, so what do you do?

Letting the aspect ratio distort to fit the containing replaced element nearly always looks horrible. And doing some kind of dynamic cropping or resizing on the fly each time might be more work than you have the capability to implement. (For instance, maybe you’re working on a CMS and don’t have permission to edit anything except the page content.)

The CSS Image Values and Replaced Content module provides properties called object-fit — which solves such problems, and object-position — which sets the horizontal and vertical position of the content inside the element.

These elements have decent support across modern browsers (with the exception of IE). In this article we’ll look at a few examples of how they can be used.

Note: object-fit works with SVG content, but the same effect can also be achieved by setting the preserveAspectRatio="" attribute in the SVG itself.

How do object-fit and object-position work?

You can successfully apply object-fit to any replaced element, for example:

The five possible values of object-fit are as follows:

  1. contain: The content (e.g. the image) will be resized so that it is fully displayed with intrinsic aspect ratio preserved, but still fits inside the dimensions set for the element.
  2. fill: The content will expand to exactly fill the dimensions set for the element, even if this does break its aspect ratio.
  3. cover: Preserves the aspect ratio of the content, but alters the width and height so that the content completely covers the element. The smaller of the two is made to fit the element exactly, and the larger overflows the element.
  4. none: Completely ignores any height or weight set on the element, and just uses the replaced element content’s intrinsic dimensions.
  5. scale-down: The content is sized as if none or contain were specified, whichever would result in a smaller replaced element size.

object-position works in exactly the same way as background-position does for background images; for example:

The only exception seems to be that percentages don’t work.

Note: You can see some object position examples in our basic example page.

The effects of the different object-fit values

The following code examples show the effects of the different object-fit values.

Letterboxing images with object-fit: contain

Sometimes referred to as letter-boxing, there are times when you will want to preserve the aspect ratio of the images on a page, but get them to fit inside the same area. For example, you might have a content management system that allows you to upload products on an e-commerce site or images for an image gallery, with lots of different content authors. They may upload images in roughly the right size, but the dimensions are not always exact, and you want to fit each image into the same amount of space.

Having images with the aspect ratio shifted usually looks horrible, so you can letterbox them instead with object-fit: contain (object-fit: contain example):

Cropping images with object-fit:cover

A different solution is to maintain aspect ratio, but crop each image to the same size so it completely envelops the <img> element, with any overflow being hidden. This can be done easily with object-fit:cover (object-fit: cover example):

Overriding a video’s aspect ratio with object-fit: fill

Going in the opposite direction, it is also possible to take a video and force it to change aspect ratio. Maybe some of your content editor’s videos have a broken aspect ratio, and you want to fix them all on the fly, in one easy fell swoop?

Take the following video image:

a video with a broken aspect ratioIf we embedded it into a page with this:

It would look terrible: the video would appear letter-boxed, since the <video> element always tries to maintain the source file’s intrinsic aspect ratio. We could fix this by applying object-fit: fill (object-fit: fill example):

This overrides the video’s intrinsic aspect ratio, forcing it to completely fill the <video> element so it displays correctly.

Interesting transition effects

Combining object-fit and object-position with CSS transitions can lead to some pretty interesting effects for image or video galleries. For example:

Only a small part of the image is shown, and the element grows to reveal more of the image when it is focused/hovered (object-fit: none example).

This is because by setting object-fit: none on the <img>, we cause the content to completely ignore any width and height set earlier, and spill out of the sides of the element. We then use overflow: hidden to crop anything that spills out. A transition is then used to smoothly increase the size of the <img> element when it’s hovered/focused, which reveals more of the image.

Gallery example

To show a slightly more applied usage of object-fit, we have created a gallery example:

an image gallery showing sixteen pictures in a four by four grid

an image gallery showing one large image

The 16 images are loaded via XHR, and inserted into the images as ObjectURLs.

Each image in turn is given an onclick handler so that when clicked the images appear full size, filling the screen (the main image, initially set to display: none; in the CSS is given a class of blowup, which makes it display and fill the whole screen; the main image’s src is then set to the same object URL as the thumb that was clicked).

Clicking a full size image makes it disappear again.

All the sizing is done with percentages so that the grid remains in proportion whatever the screen size.

Note: the thumbnails have all been given tabindex="0" to make them focusable by tabbing (you can make anything appear in the page’s tab order by setting on tabindex="0" on it), and the onclick handler that makes the full size images appear has been doubled up with an onfocus handler to provide basic keyboard accessibility:

The clever parts come with the usage of object-fit:

  1. The thumbnails: These have object-fit: cover set on them so that all image thumbs will appear at the same size, at the proper aspect ratio, but cropped different amounts. This looks pretty decent, and creates a nice effect when you resize the window.
  2. The main image: This has object-fit: contain and object-position: center set on it, so that it will appear in full, at the correct aspect ratio and as big as it can be.

Originally posted here:  

This post was originally published at Exploring object-fit