How to Use CSS object-fit and object-position

Ralph Mason
Share

There are lots of options for sizing and positioning background images with the CSS background-size and background-position properties. The object-fit and object-position properties allow us to do similar things with embedded images (as well as other replaced elements like videos). In this article, we’ll dig into how to use object-fit to fit images into a specific amount of space, and how to use object-position to get the positioning within that space just right.

Table of Contents
  1. What object-fit Is For
  2. How object-fit Works
  3. Fitting an Image into a Container with object-fit
  4. Using object-fit without a Container
  5. Using object-fit in Responsive Layouts
  6. Setting the Position of Images with object-position
  7. Conclusion

What object-fit Is For

Sometimes an image is too big for the space we want it to fit into. In the past, we would either have to crop the image in an image editor, or resize the image by setting width and/or height constraints (an imperfect option), or perform some kind of complicated clipping, or perhaps resort to using a background image instead (which is a pity if the image isn’t just for decoration).

The object-fit property does for images what background-size does for background images: it provides options for how an image is displayed within a designated area, hiding some of it if necessary. This designated area might have a fixed width and height, or it may be a more responsive space such as a grid area that grows, shrinks and flexes depending on the size of the browser’s viewport.

How object-fit Works

Every HTML element has its own “content box”, which represents the space it occupies. By default, the content box of an image matches the image’s natural dimensions.

When we apply a different width and/or height to an image, we’re really changing the dimensions of the content box. If the dimensions of the content box change, the image will still fill the content box. So if we have a 300px by 300px image and set its dimensions to 300px by 200px, the image will appear distorted.

The object-fit property gives us options for how the image is displayed within that resized content box. Instead of it appearing distorted, we can hide part of the image, or force the image to only partially fill its content box so that it’s fully visible and not distorted.

Setting Up

To illustrate in detail how the object-fit property works, we’ll place an image inside a div that’s centered using Grid layout. The div has a brown background, and a dotted border provided by the ::before pseudo-element that will help us understand what’s happening with the image.

See the Pen
object-fit: setup
by SitePoint (@SitePoint)
on CodePen.

For our image demos, we’ll use the following image (of Oia on Santorini, Greece). Its natural dimensions are 400px by 600px.

Portrait image of a village by the sea

Our image is much larger than our div, and if we place the image inside the div, it will spill out, as shown below.

See the Pen
object-fit: setup2
by SitePoint (@SitePoint)
on CodePen.

Our goal is to prevent the image from bursting out of its container like this, but also to have it fit comfortably within it, and object-fit will help us do that.

If we were working with a background image, we could set something like background-size: cover and the background image would be constrained to the area of the container. But as we’ve seen, for object-fit to do anything useful, we first need to define a height and width on the image’s content box that’s different from its natural size. In the examples below, we’ll constrain the width and height of the image to 100%, so that its content box matches the size of the container div:

img {
  width: 100%;
  height: 100%;
}

Here’s what that looks like.

See the Pen
object-fit: setup3
by SitePoint (@SitePoint)
on CodePen.

The image and its content box now fit snugly within the container, but the image is badly distorted. This is where the magic of object-fit comes to our rescue, so let’s see what it has to offer.

Fitting an Image into a Container with object-fit

The object-fit property offers five main keyword values for determining how our image will be displayed within its container. Two of those keywords — cover and contain — perform the same role as their background-size cousins.

object-fit: cover

The cover value forces the image to completely cover the area of the container, showing as much of the image as possible without distorting it:

img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

See the Pen
object-fit: cover
by SitePoint (@SitePoint)
on CodePen.

Because the image is quite tall, we see its full width but not its full height, as illustrated in the image below.

The cover value ensures that the narrower part of the image fully fills the container

The cover value is probably the most useful of those on offer, being the go-to option in most circumstances.

It’s worth noting here the positioning of the image. Unlike background-position, which defaults to 0 0 (positioning the background image from the top left of the container), the default object-position is 50% 50%, which centers the image in its content box. When we look at the object-position property later, we’ll learn how to specify which part of the image is visible.

object-fit: contain

The contain value forces the image to fit entirely within its content box but without distortion. The image retains its natural aspect ratio, and therefore doesn’t fill its container:

img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

See the Pen
object-fit: contain
by SitePoint (@SitePoint)
on CodePen.

It might seem like we would get the same result above by just setting height: 100% on the image and nothing else. But not quite, as that would leave the image positioned to the left rather than in the center, which is the default with object-fit. In combination with object-position, object-fit provides more options for how the image is positioned within the container.

object-fit: none

The none property allows the image to maintain its natural, original dimensions. Only as much of it as can fit in the resized content box is visible.

See the Pen
object-fit: none
by SitePoint (@SitePoint)
on CodePen.

Unlike with object-fit: cover, our image isn’t forced to be completely visible along at least one axis. The original image is wider and taller than the content box, so it spills out in both directions, as illustrated below.

The none value keeps the image at its normal size, so that the top, bottom and sides of the image are not seen in the container

Note, again, that the center of the image aligns with the center of the content box by default.

Also note that object-fit: none doesn’t mean object-fit is doing “nothing”. As we can see, it’s doing a lot compared with no object-fit setting at all. (See what happens in the Pen above if you remove object-fit: none as a reminder.)

object-fit: scale-down

The scale-down property either does the same as none or contain. It chooses whichever will result in the image appearing smaller.

See the Pen
object-fit: scale-down
by SitePoint (@SitePoint)
on CodePen.

Obviously, in our current example, contain is what it will choose, because our container is smaller than the image. If our container were larger than the image, none would prevail, and the image would stay at its natural size rather than fill the container in one direction, as you can see in this CodePen demo.

object-fit: fill

If we change the object-fit value to fill in our demo, it’s as if object-fit isn’t set at all. That’s because, by default, the image fills its content box no matter what dimensions are set.

See the Pen
object-fit: fill
by SitePoint (@SitePoint)
on CodePen.

Because the fill property is likely to distort an image, it’s probably not the best one to turn to in most cases.

Using object-fit without a Container

In the examples above, we’ve been using object-fit to size an image within a div container, but the principles we’ve seen in practice work just as well without that container. What’s important is the size of the image’s content box and how the image is displayed within that box.

For example, we could apply the following CSS to the image, without any surrounding div:

img {
  width: 300px;
  height: 300px;
  object-fit: contain;
}

The result is shown in the CodePen demo below.

See the Pen
object-fit: no container
by SitePoint (@SitePoint)
on CodePen.

Try changing the values on the object-fit property in the Pen above to cover, fill, scale-down and none to see how each behaves. The results are the same as if the image were set to width and height of 100% and contained within a div set to 300px by 300px.

Using object-fit in Responsive Layouts

The object-fit property is probably most useful in situations where the dimensions of the image’s designated area respond to the size of the browser viewport. The following demo assigns our image to a specific, flexible grid area:

img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  grid-row: 2 / 3; 
  grid-column: 2 / 3;
}

article {
  display: grid; 
  grid-template: 5% 1fr 10% / 40% 1fr 40%; 
  height: 100vh;
}

See the Pen
object-fit in a responsive area
by SitePoint (@SitePoint)
on CodePen.

As the viewport and grid areas expand and contract, the cover value ensures that the image always fits nicely into its grid area, changing how much of the image is visible so that it’s never distorted. (Check out the demo in full page view to get the best sense of this.)

To learn more about grid areas, check out our beginner’s guide to CSS Grid.

Setting the Position of Images with object-position

Just as background-position is used to set the positioning of a background image within its container, the object-position property is used to control the positioning of an image element within its own content box.

As we’ve seen, object-position defaults to 50% 50%, which means that the center of the image aligns with the center of its content box. We can change that with a range of keyword values (top, bottom, left, right, center), or by using length values (such as px, em, or %), or by using combinations of both.

Let’s say we now want to position our image from the bottom right. We could use the keywords right bottom, or percentage values 100% 100%:

img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: right bottom; /* or 100% 100% */
}

See the Pen
object-position 1: keywords
by SitePoint (@SitePoint)
on CodePen.

The image below illustrates the positioning of our image now.

Our image now is positioned from the bottom right, so that the top part of the image is hidden

You can play around with the positioning keywords in the Pen above to see how they work, along with the object-fit keywords, but the results should be easy to predict.

We can also offset the image from its container with units such as pixels or ems. For example:

img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 20px 2em; /* 20px from left and 2em from top */
}

See the Pen
object-position 2: units
by SitePoint (@SitePoint)
on CodePen.

We could do a similar offset from the bottom right by combining units and keywords, like so:

img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: right 20px bottom 2em; /* 20px from right and 2em from bottom */
}

See the Pen
object-position 3: units and keywords
by SitePoint (@SitePoint)
on CodePen.

We’ve seen already that we can position our image in its content box with percentages. As with the background-position property, using percentages with object-position can get a bit confusing. An object-position of 50% 50% means that the center of the image aligns with the center of its content box on both horizontal and vertical axes.

If we set the object-position to 20% 40%, it means that a vertical line 20% from the left of the image coincides with a vertical line 20% from the left of the content box, and a horizontal line 40% from the top of the image coincides a horizontal line 40% from the top of the content box, as illustrated below.

Vertical and horizontal lines at 20% and 40% of the image and container in alignment

We can see this in practice in the CodePen demo below.

See the Pen
object-position 4: percentages
by SitePoint (@SitePoint)
on CodePen.

Conclusion

The object-fit property is designed to work with any kind of replaced elements, such as images, videos, iframes and embeds. Quite how useful it is to fit elements like videos into a defined area (where some of the element might be hidden) is perhaps a matter for debate, but no doubt there are viable use cases. A better option might be to set the width of an iframe to width: 100% of the available space and then use the aspect-ratio property to preserve its proportions.

It’s more common to have a specific amount of space in which an image needs to fit, so object-fit is very useful for allowing the image to fit into that space without being distorted (even if some of it has to be hidden).

To learn more about object-fit and object-position, check out the MDN pages for these properties:

Finally, as noted above, it’s worth comparing the object-fit and object-position properties with the background-size and background-position properties, which have a lot of similarities. Check out How to Use CSS background-size and background-position to get up to speed with them.