[html] Auto Resize Image in CSS FlexBox Layout and keeping Aspect Ratio?

I've used the CSS flex box layout which appears as shown below:

enter image description here

If the screen gets smaller it turns into this:

enter image description here

The problem is that the images are not resized keeping the aspect ration from the original image.

Is it possible to use pure CSS and the flex box layout to let the images be resized if the screen gets smaller?

Here is my html:

<div class="content">
  <div class="row"> 
    <div class="cell">
      <img src="http://i.imgur.com/OUla6mK.jpg"/>
    </div>
    <div class="cell">
      <img src="http://i.imgur.com/M16WzMd.jpg"/>
    </div>
  </div>
</div>

my CSS:

.content {
    background-color: yellow;    
}

.row {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;

    -webkit-box-orient: horizontal; 
    -moz-box-orient: horizontal;
    box-orient: horizontal;
    flex-direction: row;

    -webkit-box-pack: center;
    -moz-box-pack: center;
    box-pack: center;
    justify-content: center;

    -webkit-box-align: center;
    -moz-box-align: center;
    box-align: center;  
    align-items: center;

    background-color: red;

}

.cell {
    -webkit-box-flex: 1;
    -moz-box-flex: 1;
    box-flex: 1;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto; 

    padding: 10px;
    margin: 10px;

    background-color: green;
    border: 1px solid red;
    text-align: center;

}

This question is related to html css flexbox

The answer is


I came here looking for an answer to my distorted images. Not totally sure about what the op is looking for above, but I found that adding in align-items: center would solve it for me. Reading the docs, it makes sense to override this if you are flexing images directly, since align-items: stretch is the default. Another solution is to wrap your images with a div first.

.myFlexedImage {
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
}

I suggest looking into background-size options to adjust the image size.

Instead of having the image in the page if you have it set as a background image you can set:

background-size: contain

or

background-size: cover

These options take into account both the height and width when scaling the image. This will work in IE9 and all other recent browsers.


I am using jquery or vw to keep the ratio

jquery

function setSize() {
    var $h = $('.cell').width();
    $('.your-img-class').height($h);
}
$(setSize);
$( window ).resize(setSize); 

vw

 .cell{
    width:30vw;
    height:30vw;
}
.cell img{
    width:100%;
    height:100%;
}

You might want to try the very new and simple CSS3 feature:

img { 
  object-fit: contain;
}

It preserves the picture ratio (as when you use the background-picture trick), and in my case worked nicely for the same issue.

Be careful though, it is not supported by IE (see support details here).


That's how I would handle different images (sizes and proportions) in a flexible grid.

_x000D_
_x000D_
.images {_x000D_
  display: flex;_x000D_
  flex-wrap: wrap;_x000D_
  margin: -20px;_x000D_
}_x000D_
_x000D_
.imagewrapper {_x000D_
  display: flex;_x000D_
  justify-content: center;_x000D_
  align-items: center;_x000D_
  width: calc(50% - 20px);_x000D_
  height: 300px;_x000D_
  margin: 10px;_x000D_
}_x000D_
_x000D_
.image {_x000D_
  display: block;_x000D_
  object-fit: cover;_x000D_
  width: 100%;_x000D_
  height: 100%; /* set to 'auto' in IE11 to avoid distortions */_x000D_
}
_x000D_
<div class="images">_x000D_
  <div class="imagewrapper">_x000D_
    <img class="image" src="https://via.placeholder.com/800x600" />_x000D_
  </div>_x000D_
  <div class="imagewrapper">_x000D_
    <img class="image" src="https://via.placeholder.com/1024x768" />_x000D_
  </div>_x000D_
  <div class="imagewrapper">_x000D_
    <img class="image" src="https://via.placeholder.com/1000x800" />_x000D_
  </div>_x000D_
  <div class="imagewrapper">_x000D_
    <img class="image" src="https://via.placeholder.com/500x800" />_x000D_
  </div>_x000D_
  <div class="imagewrapper">_x000D_
    <img class="image" src="https://via.placeholder.com/800x600" />_x000D_
  </div>_x000D_
  <div class="imagewrapper">_x000D_
    <img class="image" src="https://via.placeholder.com/1024x768" />_x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_


HTML:

<div class="container">
    <div class="box">
        <img src="http://lorempixel.com/1600/1200/" alt="">
    </div>
</div>

CSS:

.container {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: stretch;

  width: 100%;
  height: 100%;

  border-radius: 4px;
  background-color: hsl(0, 0%, 96%);
}

.box {
  border-radius: 4px;
  display: flex;
}

.box img {
  width: 100%;
  object-fit: contain;
  border-radius: 4px;
}

In the second image it looks like you want the image to fill the box, but the example you created DOES keep the aspect ratio (the pets look normal, not slim or fat).

I have no clue if you photoshopped those images as example or the second one is "how it should be" as well (you said IS, while the first example you said "should")

Anyway, I have to assume:

If "the images are not resized keeping the aspect ration" and you show me an image which DOES keep the aspect ratio of the pixels, I have to assume you are trying to accomplish the aspect ratio of the "cropping" area (the inner of the green) WILE keeping the aspect ratio of the pixels. I.e. you want to fill the cell with the image, by enlarging and cropping the image.

If that's your problem, the code you provided does NOT reflect "your problem", but your starting example.

Given the previous two assumptions, what you need can't be accomplished with actual images if the height of the box is dynamic, but with background images. Either by using "background-size: contain" or these techniques (smart paddings in percents that limit the cropping or max sizes anywhere you want): http://fofwebdesign.co.uk/template/_testing/scale-img/scale-img.htm

The only way this is possible with images is if we FORGET about your second iimage, and the cells have a fixed height, and FORTUNATELY, judging by your sample images, the height stays the same!

So if your container's height doesn't change, and you want to keep your images square, you just have to set the max-height of the images to that known value (minus paddings or borders, depending on the box-sizing property of the cells)

Like this:

<div class="content">
  <div class="row">    
      <div class="cell">    
          <img src="http://lorempixel.com/output/people-q-c-320-320-2.jpg"/>
      </div>
      <div class="cell">    
          <img src="http://lorempixel.com/output/people-q-c-320-320-7.jpg"/>
      </div>
    </div>
</div>

And the CSS:

.content {
    background-color: green;
}

.row {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;

    -webkit-box-orient: horizontal; 
    -moz-box-orient: horizontal;
    box-orient: horizontal;
    flex-direction: row;

    -webkit-box-pack: center;
    -moz-box-pack: center;
    box-pack: center;
    justify-content: center;

    -webkit-box-align: center;
    -moz-box-align: center;
    box-align: center;  
    align-items: center;

}

.cell {
    -webkit-box-flex: 1;
    -moz-box-flex: 1;
    box-flex: 1;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 10px;
    border: solid 10px red;
    text-align: center;
    height: 300px;
    display: flex;
    align-items: center;
    box-sizing: content-box;
}
img {
    margin: auto;
    width: 100%;
    max-width: 300px;
    max-height:100%
}

http://jsfiddle.net/z25heocL/

Your code is invalid (opening tags are instead of closing ones, so they output NESTED cells, not siblings, he used a SCREENSHOT of your images inside the faulty code, and the flex box is not holding the cells but both examples in a column (you setup "row" but the corrupt code nesting one cell inside the other resulted in a flex inside a flex, finally working as COLUMNS. I have no idea what you wanted to accomplish, and how you came up with that code, but I'm guessing what you want is this.

I added display: flex to the cells too, so the image gets centered (I think display: table could have been used here as well with all this markup)


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to flexbox

Force flex item to span full row width vuetify center items into v-flex Equal height rows in CSS Grid Layout display: flex not working on Internet Explorer Center the content inside a column in Bootstrap 4 Vertical Align Center in Bootstrap 4 How to use zIndex in react-native Bootstrap 4 align navbar items to the right Does 'position: absolute' conflict with Flexbox? Make flex items take content width, not width of parent container