logo
post image

Crop Images in CSS with object-fit and object-position

Images can be cropped with CSS using the object-fit property. The position of the crop can be changed using object-position property.

If we try to crop an image by setting a specific width and height in CSS, the aspect ratio of the <img> element becomes different from aspect ratio of the original image and it is either shown stretched or compressed in the page.

As an example consider the following image, original dimensions being 600 pixels wide and 311 pixels in height :

Assuming that we have to adjust the image in a container of size 200px * 200px, the result would look something like :

The image is squished, and does not look.

This situation can be perfectly handed using object-fit and object-position CSS properties. These properties are similar to background-size and background-position properties, but can be applied directly to <img> elements.

FAQ — Difference Between Image vs Image Content Box

Image refers to the original image — it will have its own width and height.

The image content box refers to the <img> element inside the webpage — which is basically a box. You set its width and height using CSS.

.image {
	width: 200px;
	height: 200px;
}

An image is fitted inside its content box in a webpage.

Step 1 — Resizing & Scaling Image to Fit Inside the Container Using object-fit

The object-fit property defines the way an image has to be resized to fit in the image's content box. object-fit accepts the following values :

  • contain : The image is resized (scaled up or down) to preserve the aspect ratio while fitting it inside the image's content box. The attempt here is to fill the entire box if the aspect ratio of the image is same as that of the box. If the aspect ratio is different, the image is letterboxed inside the box. In letterboxing, areas that are not covered will be filled by the background-color of the image.

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

    In the above case, the original image is scaled down to preserve the aspect ratio. But because the aspect ratio of the image's content box is not same as that of the image, the image is shown letterboxed. You can set a background-color for the image to give a background color for the letterboxed areas, otherwise the background color is inherited.

    img {
    	width: 200px;
    	height: 200px;
    	object-fit: contain;
    	background-color: #bdc3c7;
    }
    
  • cover : The image in this case is also resized to preserve the aspect ratio while fitting it inside in the image box. The attempt here, is also, to fill the box if the aspect ratio is same to that of the box's. If the aspect ratio is different, the image is clipped or stretched to fit inside the box. No letterboxing happens here.

    img {
    	width: 200px;
    	height: 200px;
    	object-fit: cover;
    }
    

    object-fit: cover is somewhat like background-size: cover. The image covers the full area and may be clipped for doing so.

  • fill : The image is sized to fill the box. If the aspect ratio is not same as that of it's box, the image will either be stretched or compressed to fill it's box entirely. The aspect ratio of the image is not preserved here. This is the default value.

    img {
    	width: 200px;
    	height: 200px;
    	object-fit: fill;
    }
    
  • none : The image is not resized and is displayed as is. If the image fits inside it's content box, it is displayed entirely else a cropped image is displayed. Letterboxing may happen if the size of the content box is larger than the image. Aspect ratio is preserved here.

    In object-fit: contain, image is resized. But in object-fit: none, image is not resized.

  • scale-down : The effect is similar to contain or none, whichever results a smaller image.

    img {
    	width: 200px;
    	height: 200px;
    	object-fit: scale-down;
    }
    

Step 2 — Positioning Resized Image Inside Container with object-position

After cropping the image with object-fit, you may want to change the part of the image displayed inside. You can do this with object-position.

Just like background-position, this property also accepts position values.

object-position: right top;
object-position: 10px 30px;
object-position: 10% 15%;

As an example, suppose in the previous image, you would like the calendar to be displayed. The CSS would be like :

img {
	width: 200px;
	height: 120px;
	object-fit: none;
	object-position: -150px -40px;
}

The resulting image :

Further References