Why isn't object-fit working in flexbox?
I have several columns that I am giving equal width using flex. Each contains img
tags, and I'd like those images to exhibit the object-fit: cover
sizing.
.container {
display: flex;
flex-direction: row;
width: 100%;
}
.test {
flex: 1;
margin-right: 1rem;
overflow: hidden;
height: 400px;
}
img {
object-fit: cover;
}
<div class="container">
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
</div>
The images are not resizing, as can be seen in this demo. Why is that?
From the specification:
The
object-fit
property specifies how the contents of a replaced element should be fitted to the box established by its used height and width.
The key term being: fitted to the box established by its used height and width
The image gets replaced, not its container. And the box established by its used height and width relates to the image itself, not its container.
So, scrap the container and make the images themselves the flex items.
.container {
display: flex;
flex-direction: row;
width: 100%;
}
img {
object-fit: cover;
flex: 1;
margin-right: 1rem;
overflow: hidden;
height: 400px;
}
<div class="container">
<img src="http://placehold.it/1920x1080">
<img src="http://placehold.it/1920x1080">
<img src="http://placehold.it/1920x1080">
<img src="http://placehold.it/1920x1080">
</div>
Revised Codepen
Additional Details
5.5. Sizing Objects: the
object-fit
propertyThe
object-fit
property specifies how the contents of a replaced element should be fitted to the box established by its used height and width.Here are three of the values:
cover
The replaced content is sized to maintain its aspect ratio while filling the element's entire content box.
contain
The replaced content is sized to maintain its aspect ratio while fitting within the element's content box.
fill
The replaced content is sized to fill the element's content box.
With cover
the image retains its aspect ratio and covers all available space. With this option, much of an image may be cropped off-screen.
With contain
the aspect ratio is also maintained, but the image scales to fit within the box. This may result in whitespace on the left and/or right (portrait fit), or top and/or bottom (landscape fit). The object-position
property can be used to shift the image within its box.
With fill
the aspect ratio is abandoned and the image is sized to fit the box.
Browser Compatibility
As of this writing, object-fit
is not supported by Internet Explorer. For a workaround see:
- Neat trick for CSS
object-fit
fallback on Edge (and other browsers) - fitie - An
object-fit
polyfill for Internet Explorer - object-fit-images - Adds support for
object-fit
on IE9, IE10, IE11, Edge and other old browsers - Polyfill (mostly IE) for CSS
object-fit
property to fill-in/fit-in images into containers.
The problem is that object-fit
specifies how an image is painted inside the img
, but you didn't specify the sizes of these elements, only the sizes of their .test
parents.
So an alternative to Michael_B's answer is making the images have the same size as the flex items:
img {
height: 100%;
width: 100%;
object-fit: cover;
}
.container {
display: flex;
flex-direction: row;
width: 100%;
}
.test {
flex: 1;
margin-right: 1rem;
overflow: hidden;
height: 400px;
}
img {
height: 100%;
width: 100%;
object-fit: cover;
}
<div class="container">
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
<div class="test"><img src="http://placehold.it/1920x1080"></div>
</div>
For anyone who can't just "scrap the container and make the images themselves the flex items," just add container levels:
<div class="display-flex">
<div class="flex-grow position-relative">
<div class="pos-absolute top-left-right-bottom-0">
<img class="object-fit-cover height-width-100">