max-width of img inside flexbox doesn't preserve aspect ratio
How to fix IE and Firefox
The following changes should result in the same result across Chrome, Firefox and IE:
- Add
flex: 0 0 auto;
to.flex-item img
. This fixes IE - Add
object-fit: scale-down;
to.flex-item img
. This fixes Firefox
.flex-container {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
-ms-flex-flow: row wrap;
flex-flow: row wrap;
justify-content: flex-start;
}
.flex-item {
height: 222px;
width: 200px;
border: 1px solid lightgray;
padding: 5px;
margin: 5px;
}
.flex-item img {
flex: 0 0 auto;
max-width: 100%;
max-height: 100%;
align-self: center;
-webkit-align-self: center;
margin: auto;
object-fit: scale-down;
}
.item-image {
border: 1px solid lightgray;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
width: 190px;
height: 120px;
}
<div class="flex-container">
<div class="flex-item">
<div class="item-image">
<img src="http://www.joshuacasper.com/contents/uploads/joshua-casper-samples-free.jpg">
</div>
</div>
<div class="flex-item">
<div class="item-image">
<img src="https://c1.staticflickr.com/9/8264/8700922582_d7b50280b4_z.jpg">
</div>
</div>
<div class="flex-item">
<div class="item-image">
<img src="http://www.pinaldave.com/bimg/ilovesamples.jpg">
</div>
</div>
<div class="flex-item">
<div class="item-image">
<img src="http://appslova.com/wp-content/uploads/2014/11/Android-.png">
</div>
</div>
</div>
Maintain image aspect ratio when changing height
For img tags if you define one side then other side is resized to keep aspect ratio and by default images expand to their original size.
Using this fact if you wrap each img tag into div tag and set its width to 100% of parent div then height will be according to aspect ratio as you wanted.
http://jsfiddle.net/0o5tpbxg/
* {
margin: 0;
padding: 0;
}
.slider {
display: flex;
}
.slider .slide img {
width: 100%;
}
Why does flexbox stretch my image rather than retaining aspect ratio?
It is stretching because align-self
default value is stretch
.
Set align-self
to center
.
align-self: center;
See documentation here:
align-self
Auto Resize Image in CSS FlexBox Layout and keeping Aspect Ratio?
img {max-width:100%;}
is one way of doing this. Just add it to your CSS code.
http://jsfiddle.net/89dtxt6s/
CSS Flexbox images not preserving aspect ratio
I'm currently working on a similar problem and it seems to be a bit tricky. I found a solution which works in safari, but won't work in chrome and firefox. They ignore the
max-height: 100%;
property. Check this out and resize browser.
Although i'm not 100% sure what you are trying to achieve (your codepen doesn't change anyhow when resizing the browser window), i've build this one.
Let me know if it's the right direction
Why does width and height of a flex item affect how a flex item is rendered?
An initial setting of a flex container is align-items: stretch
.
That means that flex items will expand across the cross axis of the container.
In a row-direction container, like in the question, the cross axis is vertical.
That means the items (images, in this case) will cover the full height of the container.
However, when a flex item has a defined cross size, that overrides the stretch
default.
From the spec:
8.3. Cross-axis Alignment: the
align-items
andalign-self
propertiesFlex items can be aligned in the cross axis of the current line of the
flex container, similar tojustify-content
but in the perpendicular
direction.
stretch
If the cross size property of the flex item computes to
auto
, and
neither of the cross-axis margins areauto
, the flex item is
stretched.
This is the key language:
If the cross size property of the flex item computes to
auto
And this is how the spec defines "cross size property":
The width or height of a flex item, whichever is in the cross
dimension, is the item’s cross size. The cross size property is
whichever ofwidth
orheight
that is in the cross dimension.https://www.w3.org/TR/css-flexbox-1/#cross-size-property
So your code appears to be playing out as defined in the spec.
This is what you have:
.flex-parent { display: flex; max-height: 10vh;}
<div class="flex-parent"> <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg"> <img width="320" height="240" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg"></div>
CSS - Keep image aspect ration flexbox
Unless you have very specific requirements, I suggest Masonry:
a JavaScript grid layout library. It works by placing elements in
optimal position based on available vertical space, sort of like a
mason fitting stones in a wall. You’ve probably seen it in use all
over the Internet.
in combination with imagesLoaded For a versatile lightweight solution.
There are many ways to implement Masonry.
The following is my personal favorite.
All my comments are inside the snippet below
body { background: #131418;}
/* Step 1: start with resetting some defaults */
* { margin: 0 auto; padding: 0; max-width: 100%;}
/* Step 2: center things inside the grid and clear some space around it by setting a device based max-width and margin*/
.grid { text-align: center; max-width: 95vw; margin: 2.5vw auto;}
/* Step 3: how big should the gap be between grid items? remember that the total gap between two items would be double what you set here since both would have that amount set as their individual padding. Also add box-sizing:border-box to make sure the padding doesn't affect the total widh of the item */
.grid-item { padding: 5px; box-sizing: border-box;}
/* Step 4: Add media queries (subjective) to make the whole grid resposive. */
@media (min-width: 500px) { .grid-item { width: 50%; }}
@media (min-width: 1000px) { .grid-item { width: 33.333%; }}
@media (min-width: 1700px) { .grid-item { width: 25%; }}
@media (min-width: 2100px) { .grid-item { width: 20%; }}
<!-- Made possible by the great work of David DeSandro @ https://masonry.desandro.com -->
<!-- Part 1: Add the scripts -->
<!-- Step 1: Let's start by loading jQuery. jQuery is not required for masonary to function but makes things easier --><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Step 2: Then load imagesloaded. imagesloaded makes sure the images are not displayed until they are fully loaded --><script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>
<!-- Step 3: we load masonry --><script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
<!-- Part 2: Create the grid -->
<!-- Step 1: Start with a the main grid wrapper--><div class="grid">
<!-- Step 2: Add grid items--->
<div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/736x/00/37/03/0037037f1590875493f413c1fdbd52b1--cool-beards-inspiring-photography.jpg" /> </div>
<div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/736x/cd/90/d9/cd90d9de63fa2c8e5c5e7117e27b5c18--gritty-portrait-photography-studio-photography.jpg"> </div>
<!-- Step 3: repeat...---> <div class="grid-item"> <img src="https://1.bp.blogspot.com/-9QM7ciGXRkQ/V1hsB-wNLBI/AAAAAAAAMoA/eYbSHs00PTAjrI4QAmvYAIGCUe1AuRAnwCLcB/s1600/bryan_cranston_0095.jpg"> </div>
<div class="grid-item"> <img src="http://webneel.com/sites/default/files/images/project/best-portrait-photography-regina-pagles%20(10).jpg" /> </div>
<div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/736x/dd/45/96/dd4596b601062eb491ea9bb8e3a78062--two-faces-baby-faces.jpg" /> </div>
<div class="grid-item"> <img src="http://www.marklobo.com.au/news/wp-content/uploads/2013/03/Melbourne_Portrait_Photographer_Mark_Lobo-Cowboy.jpg" /> </div>
<div class="grid-item"> <img src="https://format-com-cld-res.cloudinary.com/image/private/s--PcYqe7Zw--/c_limit,g_center,h_65535,w_960/a_auto,fl_keep_iptc.progressive,q_95/145054-8576001-Rob-Green-by-Zuzana-Breznanikova_7725_b_w.jpg" /> </div>
<div class="grid-item"> <img src="http://www.iefimerida.gr/sites/default/files/janbanning11.jpg" /> </div>
<div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/736x/66/bb/e7/66bbe7acc0d64da627afef440a29714b--portrait-photos-female-portrait.jpg" /> </div>
<div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/736x/25/34/b6/2534b6c18c659546463f13b2dc62d4ce--natural-portraits-female-portraits.jpg" /> </div>
<div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/originals/8d/67/12/8d671230ced871df8428b571ed6ec192.jpg" /> </div>
</div>
<!-- Part 3: the script call -->
<!-- Now that everything is loaded we create a script to trigger masonary on $grid. Note that this simply says: "if the images are fully loaded, trigger masnory on $grid. --><script> $(".grid").imagesLoaded(function() { $(".grid").masonry({ itemSelector: ".grid-item" }); });</script>
chrome doesn't respect image aspect ratio in flexbox
The items in a flexbox will stretch their size by default.
Seeing you want them to not stretch on the cross-axis (vertical), you can use the align-items
on the container, to change the default behaviour.
Fiddle: http://jsfiddle.net/g1vLff23/
CSS
.flexbox {
width: 100%;
display: flex;
align-items: flex-start;
}
img {
width: 50%;
}
Related Topics
Create Angular Material Theme with CSS Variables
CSS Equivalent to Photoshop's Justify-All
What Does an * (Star) Mean in Front of a CSS Declaration
Input Padding Cutting Out Text in Firefox
Rake Assets:Precompile Throws SASS::Syntaxerror: Invalid CSS After "*/"
Css: A:Link VS Just a (Without the :Link Part)
How to Make an Entire Div Clickable with CSS
CSS with If/Then Browser Logic
Safari Rounding Down on Subpixel Calculations
Cross-Browser 'Cursor:Pointer'
Add Padding Without Changing Overall Width
Media Queries for Landscape Printing
How to Make Diagonal Circle Border Gradient
What Tag Should I Use Instead of Deprecated Tag Font in HTML (Cannot Use CSS)