CSS Object-Fit: Contain; Is Keeping Original Image Width in Layout

CSS object-fit: contain; is keeping original image width in layout

What you have is logical, you simply need to understand how object-fit works. Let's start with an easier example:

.box {  width:300px;  height:300px;  border:1px solid;}img { width:100%; height:100%; object-fit:contain;}
<div class="box">  <img src="https://picsum.photos/300/200?image=1069"></div>

Mysterious behavior when using CSS object-fit:contain property on images inside a flexbox container having a specific height

BDB88 provided me with the clue I needed, and thanks for that. My objective is to make a responsive layout that will show the drop shadow around the images and not some ghostly outline that's at a distance, and I want to keep the images' aspect ratios. I also want to mandate a particular height for the container, and not have the images overflow outside of it. My use of "height: 100%;" for the img tag was what was causing the problem. Combining that with the "width: 40%;" was causing conflict because both requirements can't always be satisfied simultaneously. By changing to "max-height: 100%;" and "max-width: 40%;" for the img tag, I'm getting the behavior that I was after. The CSS is now (I made some additional edits to make the behavior more apparent when viewing and scaling the window to simulate larger/smaller screen sizes):

.container {
background: yellow;
display: flex;
margin: 1em auto 3em auto;
width: auto;
height: 200px;
justify-content: center;
align-items: center;
}
img {
box-shadow: 8px -8px 10px #00000080;
max-width: 40%;
max-height: 100%;
margin-left: 1em;
object-fit: contain;
}

Understanding object-fit CSS property

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.

So it's neither the parent element nor the containing block but the element itself. It's a relation between the element and it's content. object-fit change the behavior of the content based on the dimension of the element.

Example with different elements sharing the same containing block:

img {
object-fit: cover;
border: 2px solid;
width: 200px;
height: 200px
}
<img src="https://picsum.photos/id/10/500/400">
<img src="https://picsum.photos/id/10/800/400">
<img src="https://picsum.photos/id/10/500/1000">
<img src="https://picsum.photos/id/10/600/300">

CSS Image size, how to fill, but not stretch?

You can use the css property object-fit. ("sets how the content of a replaced element, such as an <img> or <video>, should be resized to fit its container.")

.cover {
object-fit: cover;
width: 50px;
height: 100px;
}
<img src="http://i.stack.imgur.com/2OrtT.jpg" class="cover" width="242" height="363" />

Remove whitespace from left and right of resized image

"The requirement is that the image should scale to fit the available height while maintaining aspect ratio" - that's what it does in your code! If you would stretch the width ("to fill the whitespace"), either you would loose the aspect ratio and get a distorteded image, or - if the ratio is kept - the top and bottom of the image would be cut off since it would grow due to the extended width.

There is no other solution: Either there is some whitespace, or some of the image is cut off, or the image is distorted. Unless you change the dimensions of the parent container:

The only situation where your wish could be fulfilled: When the parent of the image has the same height/width proportion as the original image. So you would have to set height and width for the container accoring to the proportions of the image.

Object-fit not affecting images

object-fit only affects the way the picture displays inside of the img boundaries.

Object-Fit

The object-fit CSS property sets how the content of a replaced element, such as an <img> or <video>, should be resized to fit its container.

Replaced Element

elements whose contents are not affected by the current document's styles. The position of the replaced element can be affected using CSS, but not the contents of the replaced element itself.

This means that the object-fit is independent of your article elements as object-fit only cares about the dimensions of the img element.

The point of this is that you need to get the img elements to stretch to those dimensions first. The object-fit only affects the way the picture displays inside of the img boundaries.

Sample Code / Demonstration

$(function() { $("img").resizable(); });
img {
width: 300px;
height: 300px;
border: 1px solid #FF0000;
background-color: #00FF00;
}

.fill {
object-fit: fill;
}

.contain {
object-fit: contain;
}
.cover {
object-fit: cover;
}
.none {
object-fit: none;
}
.scaledown {
object-fit: scale-down;
}

.variant1 {
max-width: 100px;
}

.variant2 {
max-height: 100px;
}
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<p>Resize images to see properties with different dimensions.</p>

<h1>fill (default)</h1>
<img src="https://i.stack.imgur.com/EtYb2.jpg" class="fill" />

<h1>contain</h1>
<img src="https://i.stack.imgur.com/EtYb2.jpg" class="contain" />

<h1>cover</h1>
<img src="https://i.stack.imgur.com/EtYb2.jpg" class="cover" />

<h1>none</h1>
<img src="https://i.stack.imgur.com/EtYb2.jpg" class="none" />

<h1>scale-down</h1>
<img src="https://i.stack.imgur.com/EtYb2.jpg" class="scaledown" />
<!-- Spacer for scale down scroll annoyance -->
<br /><br /><br /><br /><br /><br /><br />

Using object-fit for a responsive image

You may need an extra div to achieve this:

.col {  width: 33.33%;  float: left;  border: 1px solid;  box-sizing: border-box;}
.col > div { position: relative}
.col > div::before { content: ""; display: inline-block; padding-top: 100%;}
.col img { position: absolute; width: 100%; height: 100%; object-fit: cover;}
<div class="col">  <div><img src="https://via.placeholder.com/480x800"></div>  <p>some text here</p></div><div class="col">  <div><img src="https://via.placeholder.com/480x1200"></div>  <p>some text here</p></div><div class="col">  <div><img src="https://via.placeholder.com/600x400"></div>  <p>some text here</p></div>


Related Topics



Leave a reply



Submit