Why Isn't Object-Fit Working in Flexbox

Why isn't object-fit working in flexbox?

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>

object-fit: fill; does not working

The object-fit property is set on the div .flexbox_item wrapping the images, they actually fill the boxes. But the images are not set to fill these divs, so they stay the same.

you can add width: 100%; height: 100%; to the images for that.

NOTE: fill will stretch your images if dimensions are not square, you can try with cover so that the initial ration is kept (image are cropped so they can fill the container)

<!doctype html><html>
<head><meta charset="utf-8"></head>
<style>.main_container { position: relative; margin: 0 5% 0% 5%; box-shadow: 0 0 10px rgba(0, 0, 0, 0.8);}
.flexbox_container { display: flex; flex-flow: row wrap; justify-content: center; align-items: stretch; align-content: stretch;}
.flexbox_item { background-color: cyan; flex-basis: 25%; object-fit: fill;}
img { vertical-align: middle; width: 100%; height: 100%;}
</style>
<body> <div class="main_container"> <div class="flexbox_container"> <div class="flexbox_item"> <img src="http://oi43.tinypic.com/14ida8p.jpg" style="width:100%" alt="First Photo"> </div> <div class="flexbox_item"> <img src="http://oi67.tinypic.com/2qd0ms0.jpg" style="width:100%" alt="Second Photo"> </div> <div class="flexbox_item"> <img src="http://oi39.tinypic.com/xpzzc.jpg" style="width:100%" alt="Third Photo"> </div> <div class="flexbox_item"> <img src="http://oi64.tinypic.com/2qd0sc0.jpg" style="width:100%" alt="Fourth Photo"> </div> <div class="flexbox_item"> <img src="http://oi49.tinypic.com/35kick3.jpg" style="width:100%" alt="Fifth Photo"> </div> <div class="flexbox_item"> <img src="http://oi65.tinypic.com/2qd1hjs.jpg" style="width:100%" alt="Sixth Photo"> </div> </div> </div></body>
</html>

Image flex item does not shrink height in a flexbox

Note that in your example, the item is the flex item and not content - you should check the strech behaviour of item here.


How can we opt out of img's special behaviour so that it behaves like
other flex items (such as div)?

It behaves like other flex items - <img> may not be very useful as a flex item but the stretch behaviour works fine:

  • if the image has more height than item, the item stretches to the height of the image
  • if the image has less height than item, the image stretches to the height of the content breaking its aspect ratio.

See demo below:

.container {  border: 1px solid;  display: flex;}
.item { background: cadetblue;}
.content { width: 200px; background-color: hotPink;}
img { display: block;}
<h2>Small content</h2><div class="container">  <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ">  <div class="item">    <div class="content">some text here some text here some text here </div>  </div></div><br/><h2>Large Content</h2><div class="container">  <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ">  <div class="item">    <div class="content">some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here </div>  </div></div>

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 />

Image with object-fit not filling container

Define dimensions for the image, then object-fit works:

.tile {    position: relative;    float: left;    margin: 10px;    border: 4px solid green;    height: 400px;}
.deal { width: 342px; background: #ffffff;}
.tileImage.promo { object-fit: fill; /* also try 'contain' and 'cover' */ width: 100%; height: 100%;}
<div class="tile deal hsNational active">  <img class="tileImage promo" src="https://cdn.pixabay.com/photo/2015/12/13/09/42/banner-1090835_960_720.jpg"></div>

Why doesn't my flexbox hover effects work as expected in IE 11?

I just wanted to follow up on this. Rather than rewrite my code -- I decided to hack around it to define a solution.

First step was to identify this is IE 10+ code in my CSS -- i did that through:

@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
/* IE10+ CSS styles go here */
}

I then redefined my flex_container and flex_item as block (using column code as follows) inside the @media query

[class*="flex_item"] {
float: left;
padding: 15px;
}

.flex_container{
display: block;
overflow: hidden;
box-sizing: border-box;
justify-content: center;
align-items: center;
text-align: center;
flex-direction: none;
font-size: 16px;
}

.flex_item {width: 8.33%;box-sizing: border-box;}

I then went through my code and changed any reference to flex to block within that code. Its a lot of duplication but it essentially got me back to @deepak-MSFTs response.

This effectively resolves my issue.

How to force images to cover the dimensions of a layout unit using flexbox and the object-fit property?

I found a solution that is working for me. The problem seems to be the missing dimensions on the anchor elements. While I tried to absolutely position the links to force them to cover their container, I should have tried more thoroughly to style them as flexbox-container as well. My solution includes the following additions:

  1. Force the anchor elements to act as flexbox-container as well, just like the gallery items do.
  2. Force each gallery item to use 100% of the height of its parent column. The flex-module will calculate the actual height used for the element and allow the item to grow or shrink as required (flex: 1 1 auto).
  3. Each image element is stretched to cover the dimensions of their container using the flex-module (using flex: 1 1 auto;). The object-fit statement will ensure the aspect-ratio is maintained.
  4. A new css class allows the blockquote-container to use just as much space as required by the contents (flex-shrink: 0; flex-grow: 0; height: auto;).

The resulting layout, was exactly what I was looking for – at least in Chrome, Firefox and IE10+. Unfortunately in Safari the result is a bit different. In Safari the blockquote-element and its contents determines the height of the entire gallery. The resulting height of each column is as a consequence divided between each child, resulting in small thumbnail images. I assume the reason is, that there is no element with a explicit height and percentage based height do not work here (wondering why it does for other browsers though). A fix which is working for my use-case was to apply a min-height on the gallery container.

Here the current solution:

// Object Fit Polyfill// @see <https://github.com/bfred-it/object-fit-images>objectFitImages();
/* #Base:Reset */
body { font: 100%/26px Lato, sans-serif; padding: 5%;}
figure { margin: 0;}
blockquote { margin-left: 0; }
img { vertical-align: middle; max-width: 100%; height: auto; font-style: italic;}
/* #Component:Gallery */
.c-gallery { display: flex; flex-flow: row nowrap; justify-content: space-between; min-height: 100vh; /* Prevents collapsing items in Safari */ max-height: 1080px;}
.c-gallery__column { display: flex; flex-flow: column nowrap; flex: 1 1 auto; width: 33.33333%; }
.c-gallery__item, .c-gallery__item > a { display: flex; flex-flow: column nowrap; flex: 1 1 auto; height: 100%; }
.c-gallery__item--fit-content { flex-grow: 0; flex-shrink: 0; height: auto; }
.c-gallery__item img { flex: 1 1 auto; width: 100%; max-width: none; height: 100%; object-fit: cover; }
<div class="c-gallery">  <div class="c-gallery__column">    <figure class="c-gallery__item">      <a href="#"><img src="http://placehold.it/640x1080" alt="Product A" /></a>    </figure>  </div>  <div class="c-gallery__column">    <div class="c-gallery__item c-gallery__item--fit-content">      <figure>        <blockquote>          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officiis architecto voluptatum numquam totam quos neque incidunt!</p>        </blockquote>        <figcaption>          <cite>John Doe</cite>        </figcaption>      </figure>    </div>    <figure class="c-gallery__item">      <a href="#"><img src="http://placehold.it/640x720" alt="John Doe" /></a>    </figure>  </div>  <div class="c-gallery__column">    <figure class="c-gallery__item">      <a href="#"><img src="http://placehold.it/640x360" alt="Product B" /></a>    </figure>    <figure class="c-gallery__item">      <a href="#"><img src="http://placehold.it/640x360" alt="Product C" /></a>    </figure>    <figure class="c-gallery__item">      <a href="#"><img src="http://placehold.it/640x360" alt="Product D" /></a>    </figure>  </div></div><script src="http://bfred-it.github.io/object-fit-images/dist/ofi.browser.js"></script>


Related Topics



Leave a reply



Submit