object-position are my two favourite CSS properties lately. They give developers control over the content inside an
img or a
video similar to the way that we can manipulate the content of a
First, let’s dig into
This property defines how an element, such as an
img, responds to the width and height of its content box. With
object-fit we can tell the content to fill that box in a variety of ways such as “preserve that aspect ratio!” or “stretch up and take up as much space as possible!”
Here’s an example:
This image is 400px x 260px. If we style that image like so…
…then we end up with awkward distortion because that image is being squished to fit that container:
The content of our
img will take up all the available space inside its new box that we created when we changed its height and width, thus destroying its original aspect ratio.
To preserve the image’s aspect ratio whilst also filling in the space, we can use
The image on the left is our original and the image on the right has cut off the sides of the image, now preserving our aspect ratio! This might not look like a particularly interesting development at this scale but once we move into designing more realistic interfaces then the power of
object-fit reveals itself.
Let’s take another example:
Here we have two images and we want them to fill the width of 50% of the browser window (so they sit side by side) and 100% of the height. This we can do with the help of viewport units:
The problem is that when we resize the browser we change the aspect ratio of the images which can cause all sorts of weirdness. Instead, we want to preserve their aspect ratio just like in the previous demo and we can use exactly the same method of doing so.
object-fit: cover to the rescue!
Try resizing the browser again. No aspect-ratio weirdness, right? This is also extraordinarily helpful if we have images that have different dimensions because they’ll effectively be cropped by their bounding box.
cover is only one of many values for
object-fit, more of which you can read about on the Almanac entry, but so far it’s the only value that I’ve found to be the most useful in day-to-day interface development.
Let’s move onto my next favourite thing:
We’ll get things set up by using the same image as before and using these styles:
Two things to note here: we need to declare the dimensions for our image in order for
object-position to work properly and we also need to set
none so that the image can be pushed around instead of filling up the whole box, as it would do by default. This makes a bit more sense when you see that the default for
object-fit on an image is
fill, even if you don’t declare it.
Speaking of defaults,
object-position centers all objects horizontally and vertically without a value:
object-position: 50% 50%; /* even if we dont declare this the image will still be centered */
The first value moves the image left or right and the second moves it up or down. We can experiment with those values here:
We can even nudge the image inside its content box so that we can reveal the
background-color that we set earlier.
But how is this useful? Good question! Well, in a recent project I found that a particular section of an image needed to be moved towards the center so that it caught the attention of the reader. We didn’t need to load a new image, and so we didn’t need the
<picture> element in this case, all we wanted to do was move the image over a little bit.
Besides moving the focus of an image, I’m not sure what else this property might be helpful for in a practical sense. But I’ve been messing around with
object-position to show how you can hide parts of an image and then reveal bits of it on click, like in this demo:
I haven’t experimented with how or why you might use this for
<video> elements. Full screen video that hits all the edges, perhaps? There’s plenty more to learn about and explore when it comes to these properties.
What’s the support?
Generally speaking, pretty good!