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
, theitem
stretches to the height of the image - if the image has less height than
item
, the image stretches to the height of thecontent
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:
- Force the anchor elements to act as
flexbox
-container as well, just like the gallery items do. - 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
). - Each image element is stretched to cover the dimensions of their container using the flex-module (using
flex: 1 1 auto;
). Theobject-fit
statement will ensure the aspect-ratio is maintained. - 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
How to Style Even and Odd Elements
Put Icon Inside Input Element in a Form
Reading HTML Content from a Uiwebview
How to Force a Line Break in a Long Word in a Div
Base64 Encoded Images in Email Signatures
Force to Open "Save As..." Popup Open At Text Link Click For Pdf in Html
How to Make a Whole Row in a Table Clickable as a Link
Html Encoding Issues - "Â" Character Showing Up Instead of "&Nbsp;"
How to Use Jsf+Facelets With HTML 4/5
Putting ≪Div≫ Inside ≪P≫ Is Adding an Extra ≪P≫
What Is Href="#" and Why Is It Used
Change Div Order With CSS Depending on Device-Width
Why Does the Outer ≪Div≫ Here Not Completely Surround the Inner ≪Div≫
Is It Wrong to Change a Block Element to Inline With CSS If It Contains Another Block Element
Is Either Get or Post More Secure Than the Other
Ie9 Float With Overflow:Hidden and Table Width 100% Not Displaying Properly