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
Most Common Way of Writing a HTML Table with Vertical Headers
How Is the Margin-Top Percentage Calculated
How to Add a Font Awesome Icon to Input Field
CSS Select Elements with Partial Id
HTML <Base> Tag and Local Folder Path with Internet Explorer
Why Is Nth-Child Selector Not Working
How to Prevent the Scrollbar Overlaying Content in Ie10
Disabling Safari Autofill on Usernames and Passwords
How to Display an .HTML Document , or .HTML Fragment at CSS Content
How to Embed a PDF Viewer in a Page
Disable Form Autofill in Chrome Without Disabling Autocomplete
How to Hide Drop Down Arrow in IE8 & IE9
Form and File Upload with HTMLservice and App Script Not Working