148

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;

}
simanacci
  • 2,197
  • 3
  • 26
  • 35
Michael
  • 32,527
  • 49
  • 210
  • 370

10 Answers10

133

img {max-width:100%;} is one way of doing this. Just add it to your CSS code.

http://jsfiddle.net/89dtxt6s/

nkron
  • 19,086
  • 3
  • 39
  • 27
Omega
  • 2,998
  • 2
  • 16
  • 19
  • 8
    Is it also possible to do this for the height dimension if the screen gets smaller? – Michael Jan 14 '14 at 00:43
  • @confile it'd depend much on your code layout, but you can try adding `height:100%;` to `img` css. – Omega Jan 15 '14 at 12:35
  • 2
    `height: 100vh` would do it, not `height: 100%`. Styling for height is always tricky. – gdbj Dec 22 '16 at 17:03
  • 1
    Why is this marked as the correct answer? Didn't Omega turned it into browser default behavior? http://jsfiddle.net/89dtxt6s/221/ – Whip Feb 07 '17 at 09:15
100

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;
}
gdbj
  • 16,102
  • 5
  • 35
  • 47
  • 20
    "I came here looking for an answer to my distorted images" i got here for the same reason and your solution helped me (what was marked as the actual solution didn't help me at all) – Wagner Danda da Silva Filho Jun 29 '16 at 17:30
  • 1
    this helped me too, can someone explain why this works ? – Jerry B. no.1 intern Aug 15 '17 at 10:22
  • 1
    This was the correct answer for me. max-width: 100%; did not correct the height (height was still slightly stretched). In my case I used align-items: flex-start; because I did not want the image vertically centered in the container, but it still worked since it overrides the default align-items: stretch; Here's a list of all the property-values for align-items you could use to override: https://www.w3schools.com/cssref/css3_pr_align-items.asp – Kyle Vassella Oct 31 '17 at 16:50
  • Tried a lot of things, but your *align-items:center* on the parent is the only one that did the trick. – Micros Dec 11 '17 at 14:31
  • This should be the accepted answer. Align-content did not work for me in terms of the stretching but align-items does, both have different functions. This SE clears up the difference between the two: https://stackoverflow.com/questions/27539262/whats-the-difference-between-align-content-and-align-items – John Ernest Jul 14 '19 at 20:40
67

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).

If you wish to specify a specific aspect ratio, you can combine it with the aspect-ratio property

img { 
  object-fit: contain;
  aspect-ratio:2/1;
}
sayandcode
  • 1,775
  • 1
  • 11
  • 24
Lokinou
  • 1,039
  • 10
  • 13
12

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.

user3196436
  • 121
  • 2
3

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)

sergio
  • 997
  • 1
  • 11
  • 15
  • It doesn't seem like you have the slightest clue of how the question was answered by me. All html and css in that jsfiddle is what the questioner ( @confile ) has provided. Just read the question and you'd see that. My solution is one simple line of css img {max-width:100%;} and the questioner has accepted my answer over one year ago as it provides the solution that was asked for. I wish you all the best here, please try to read the questions correctly and then answer accordingly in the future, thanks. – Omega Jul 27 '15 at 21:16
2

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;
}
Ukr
  • 2,411
  • 18
  • 16
1

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

.images {
  display: flex;
  flex-wrap: wrap;
  margin: -20px;
}

.imagewrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: calc(50% - 20px);
  height: 300px;
  margin: 10px;
}

.image {
  display: block;
  object-fit: cover;
  width: 100%;
  height: 100%; /* set to 'auto' in IE11 to avoid distortions */
}
<div class="images">
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/800x600" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1024x768" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1000x800" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/500x800" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/800x600" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1024x768" />
  </div>
</div>
ggzone
  • 3,661
  • 8
  • 36
  • 59
0

Set a width of 50% or a specific number for your cell div. And for the img tag, set the width to 100%. This way, the width will have to be 100% all the time and height will change accordingly keeping the aspect ratio the same.

0

You can do it easily with grid:

display: grid;
grid-template-columns: auto auto;
justify-content: space-between;
mqklin
  • 1,928
  • 5
  • 21
  • 39
-8

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%;
}
Erick Boileau
  • 478
  • 4
  • 14