4

I have an image with a height larger than that of it's container. The image is set to max-height: 100% and max-width: 100% but it continues to grow beyond it's containing element (in height - surprisingly not in width)

How do I prevent it from expanding beyond it's container while keeping it's aspect ratio?

An example is available at http://codepen.io/navarr/pen/zxZjjP, and the code at that example:

The HTML:

.row {
  display: flex;
  .col {
    display: block;
    border: 1px solid blue;
    width: 50px;
    height: 400px;
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    text-align: center;
    .link {
      flex: 1 1 auto;
      img {
        max-height: 100%;
        max-width: 100%;
      }
    }
    h3 {
      flex: 0 0 auto;
      background: green;
    }
  }
}
<div class="row">
  <div class="col">
    <div class="link">
      <img src="http://i.imgur.com/qG6NmU7.png" />
    </div>
    <h3>100 x 800 image</h3>
  </div>
  <div class="col">
    <div class="link">
      <img src="http://i.imgur.com/EjltysP.png" />
    </div>
    <h3>800 x 100 image</h3>
  </div>
  <div class="col">
    <div class="link">
      <img src="http://i.imgur.com/zJlunbp.jpg" />
    </div>
    <h3>800 x 100 image</h3>
  </div>
  <div class="col"></div>
</div>

The first box illustrates the problem: the image expanding beyond it's containing element.

The second and third box show this not being a problem as long as the image is wider than it is tall.

Nemus
  • 3,879
  • 12
  • 38
  • 57
Navarr
  • 3,703
  • 7
  • 33
  • 57
  • Would you be willing to change the `img` to a background image of the container div? – Lee Jan 15 '15 at 15:53
  • @Lee I hadn't thought of that - I'm not sure it'll be an option in the real situation, but will take a look at it. – Navarr Jan 15 '15 at 16:02
  • @Lee If you'd like to post an answer (about how it really isn't possible at this moment in time) with using a background image as a workaround, I'd be happy to mark it as the answer (until a newer answer becomes applicable or otherwise) – Navarr Jan 23 '15 at 19:57

4 Answers4

7

Add height: 100%; to the parent of the image :

.link {
  flex: 1 1 auto;
  height: 100%;

  img {
    max-height: 100%;
    max-width: 100%;
  }
}

demo

Brewal
  • 8,067
  • 2
  • 24
  • 37
  • Interestingly this works the same way in IE and Chrome, but has adverse affects in Firefox. – Navarr Jan 15 '15 at 15:57
  • 1
    Do you want the image to go under the H3 or just fill up the `.link` ? This is indeed kind of strange... I think we are facing limits of flex as it is currently implemented. Adding `min-height: 0;` to the `.link` seems to work under firefox. – Brewal Jan 15 '15 at 16:31
  • min-height: 0 under link makes it work right (in FireFox). I definitely want it to just fill up .link - Do you think this is a bug with the implementation of flexbox? – Navarr Jan 15 '15 at 16:39
  • I think so but it is quite hard to tell. I would probably use javascript here :/ – Brewal Jan 15 '15 at 16:43
  • I don't believe the "min-height:0" requirement is a bug in Firefox's flexbox implementation. (though I'm biased, as I wrote it. :)) Basically, any time the intrinsic height (or min-content main-size, in general) of a flex item is larger than the size that its flex container wants to make it, you need "min-height:0" on that flex item, to allow it to shrink below its intrinsic height, or else it'll overflow its container. See https://stackoverflow.com/questions/26895349/how-can-i-get-ff-33-x-flexbox-behavior-in-ff-34-x for more on this. – dholbert Jan 15 '15 at 21:45
  • @dholbert Giving the a min-height 0 doesn't cause it to be restrained to it's container. In Chrome the image continues to expand beyond it's container, underneath the green - in FF it expands beyond its container and pushes the green down – Navarr Jan 23 '15 at 20:00
  • Right, you need to give the *flex item* (`.link`, in this case) a min-height of 0 -- not the ``. By default, the flex item prevents itself from shrinking below its min-content height (if its container is column-oriented), which is basically the intrinsic height of its contents. And you can't reduce its contents` *intrinsic sizes* by specifying a tiny `min-height` on them. So, `min-height:0` on the `` does nothing, because the still has a nonzero intrinsic height. You need to set `min-height:0` on the *flex item* to *disable* this dependence on its contents` intrinsic sizes. – dholbert Jan 23 '15 at 21:38
4

Set width and height to .link in css.

Check edited codepen http://codepen.io/anon/pen/azJGrK

CSS

    .link {
      flex: 1 1 auto; 
      width: 100%; 
      height: 80%;
     img {
        max-height: 100%;
        max-width: 100%;
      }
Amon
  • 49
  • 2
1

Replace the img tag with a div and set the image as the background image, and add this to the styling:

Background-size:contain;

This will allow the image to maintain its aspect ratio but fill the entire space of the div as much as possible.

You can also try background-size:cover; and see which one fits your needs better.

Remember, you need to include the height and width of the div when using background images.

Lee
  • 4,187
  • 6
  • 25
  • 71
0

Using the same mentality as found in the answer here, you can try setting this on the image parent:

height: 0;
min-height: 100%;

And on the img itself, set:

height: 100%;
Sandwich
  • 475
  • 1
  • 8
  • 16