0

I have a div whose height is defined by a flex display on a enclosing div. The purpose is to display an image in this div.

My HTML5 code is :

#box {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
#container {
  flex:  1 0 auto; 
  border: 1px solid red ;
}
img {
  height:100%;
}
header,footer {
  flex: 0 0 20px;
  background-color:#aaa;
}
<div id="box">
<header>
  this is the header text
</header>
<div id="container">
  <img src="http://cimus.eu/editions/(mi)chile/webcimus/hd/001.jpg"/>
</div>
<footer>
  this is the footer text
</footer>
</div>

The #container div as the right size, adapting to window height, but the img exceeds the div height... I would like the img height to fit in the div! I hope I can find a pure CSS3 solution, avoiding JavaScript.

Thanks for any help,

Jean-David

domisol
  • 9
  • 4
  • if you want to give height 100% to the `img` to fill the vertical height, then you can expect it to overflow in the horizontal direction (see [this](http://stackoverflow.com/questions/39289576/css-image-resize-issue/39289947#39289947) too)... would be better off with `width: 100%` here I guess... – kukkuz Oct 05 '16 at 07:29
  • You're right, thanks. but max-width: 100% and/or width:auto in the img produces the same results... – domisol Oct 05 '16 at 07:38
  • @domisol You need to remove the `height: 100%;` then the width will work, see my answer, – andreas Oct 05 '16 at 07:53
  • Thanks, but the problem appears when the div height is less than the intrinsic height of the image... in this case the image is higher than the div... in any case, I want the img height to be 100% of the height of the enclosing div, the width beeing auto... – domisol Oct 05 '16 at 08:02
  • Mh, obviously this is a problem with Safari... – andreas Oct 05 '16 at 08:06
  • No Andreas, see my screenshots with Chrome, in comment to your reply... – domisol Oct 05 '16 at 08:16

6 Answers6

0

Just give the image a width:100%; without height: 100%;. This way, it will fit perfectly into the containers width while keeping its aspect ratio, even while resizing the viewport. Just giving height: 100%; will force an image with landscape orientation to overlap the container horizontally.

If there is no text in the container, you can also give the .container a font-size: 0; to avoid the white margin below.

#box {
  display: flex;
  flex-direction: column;
}
#container {
  flex: 0 1 auto;
  border: 1px solid red;
  font-size: 0;
}
img {
  width: 100%;
}
header,
footer {
  flex: 0 0 20px;
  background-color: #aaa;
}
<div id="box">
  <header>
    this is the header text
  </header>
  <div id="container">
    <img src="http://cimus.eu/editions/(mi)chile/webcimus/hd/001.jpg" />
  </div>
  <footer>
    this is the footer text
  </footer>
</div>
andreas
  • 16,357
  • 12
  • 72
  • 76
  • Thanks Andreas, but this stills make the img overflow outside of the div... the footer gets in the middle of the image... – domisol Oct 05 '16 at 07:28
  • Which browser? Seems fine in Vivaldi, Opera, Chrome, Edge and Firefox... – andreas Oct 05 '16 at 07:32
  • @domisol You need to remove the `height: 100%;`! – andreas Oct 05 '16 at 07:50
  • Here are screenshots in Chrome, without the image (correct div size) and with the image: https://s21.postimg.org/m5rrlp5tj/screenshot_chrome_without_img.jpg https://s21.postimg.org/m4htsa3zr/screenshot_chrome_with_img.jpg – domisol Oct 05 '16 at 08:13
  • updated my answer, now you always have 100vh and the image overflow is hidden - is that what you want? If yes, I will add some explanation... – andreas Oct 05 '16 at 08:26
  • Thanks again Andreas for helping. Well, not really. I understand the calc trick, but later in my flex box, I may add some other non fixed height div, so that would work. But more than all, this generates overflow, this means part of the image is hidden, which is a non-wanted behavior. The image is the most important thing of the page... – domisol Oct 05 '16 at 08:30
  • Ok sorry, then I just don't understand what you're trying to achieve... – andreas Oct 05 '16 at 08:32
  • Something very simple: have the image expand (proportionaly to its intrinsic ratio) to the space of the div! – domisol Oct 05 '16 at 08:33
  • That is achieved by simply using `width:100%;`. – andreas Oct 05 '16 at 08:46
  • sorry for interrupting the discussion here... @domisol if you want to fill the viewport height and width together without overflow, then it is not possible without breaking the aspect ratio... The best thing would be to set `width: 100%` and then allow `container` to overflow-y so that user can scroll the viewport and see the full image (or even scroll the `container`)... – kukkuz Oct 05 '16 at 08:56
  • No, what I want is fill the width of the div if the image has a bigger L/H ratio than the div, fill the height in the contrary. But as a start, we can make the asumption that image L/H ratio is lower, and then we have to fill only the height of the div (without having the div bigger !). – domisol Oct 05 '16 at 09:18
0

Just Added width:100%; in img styles . Try It Once

#box {
  display: flex;
  flex-direction: column;
  height: 100%;
  
}
#container {
  flex:  0 1 auto; 
  border: 1px solid red ;
 
 
}
img {
  height:100%;
  width:100%;
}
header,footer {
  flex: 0 0 20px;
  background-color:#aaa;
}
<div id="box">
<header>
  this is the header text
</header>
<div id="container">
  <img src="http://cimus.eu/editions/(mi)chile/webcimus/hd/001.jpg"/>
</div>
<footer>
  this is the footer text
</footer>
</div>
Samudrala Ramu
  • 2,088
  • 1
  • 15
  • 36
0

You just need to add max-width: 100% to the image element.

#box {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
#container {
  flex:  0 1 auto; 
  border: 1px solid red ;
}
img {
  max-width: 100%;
  height:100%;
}
header,footer {
  flex: 0 0 20px;
  background-color:#aaa;
}
<div id="box">
<header>
  this is the header text
</header>
<div id="container">
  <img src="http://cimus.eu/editions/(mi)chile/webcimus/hd/001.jpg"/>
</div>
<footer>
  this is the footer text
</footer>
</div>
Tom
  • 2,543
  • 3
  • 21
  • 42
0

Set IMG both height and width as 100%

#box {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
#container {
  flex:  0 1 auto; 
  border: 1px solid red ;
}
img {
  height:100%;
  width:100%;
}
header,footer {
  flex: 0 0 20px;
  background-color:#aaa;
}
<div id="box">
<header>
  this is the header text
</header>
<div id="container">
  <img src="http://cimus.eu/editions/(mi)chile/webcimus/hd/001.jpg"/>
</div>
<footer>
  this is the footer text
</footer>
</div>
Dhaarani
  • 1,350
  • 1
  • 13
  • 23
0

I've found my own solution... using js with jquery, no exactly the best thing I had dream, but I'll share it... any comments are welcome.

  var imageWidth;
  var imageHeight;
  newImg = new Image();

  $(document).ready(function() {
    newImg.src = "http://cimus.eu/editions/(mi)chile/webcimus/hd/001.jpg";
    newImg.onload = function() {
      imageWidth = newImg.width;
      imageHeight = newImg.height;
      containerWidth = $('#container').width();
      containerHeight = $('#container').height();
      $('img').attr('src', newImg.src);
      if ((imageWidth / imageHeight) > (containerWidth / containerHeight)) {
        $('img').css('width', containerWidth + "px");
      } else {
        $('img').css('height', containerHeight + "px");
      }
    };
  });

  $(window).resize(function() {
    $('img').hide();
    containerWidth = $('#container').width();
    containerHeight = $('#container').height();
    $('img').show();

    if ((imageWidth / imageHeight) > (containerWidth / containerHeight)) {
      $('img').css('width', containerWidth + "px");
      $('img').css('height', (containerWidth * imageHeight / imageWidth) + "px");
    } else {
      $('img').css('height', containerHeight + "px");
      $('img').css('width', (containerHeight * imageWidth / imageHeight) + "px");
    };
  });
#box {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

#container {
  background: blanchedalmond;
  flex: 1 0 auto;
  border: 1px solid red;
}

img {}

header,
footer {
  flex: 0 0 20px;
  background-color: #aaa;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box">
  <header>
    this is the header text
  </header>
  <div id="container">
    <img />
  </div>
  <footer>
    this is the footer text
  </footer>
</div>
domisol
  • 9
  • 4
0

Not sure what you excatly want. Somthing like this?:

#box {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
#container {
  flex:  1 0 auto; 
  border: 1px solid red ;
}
img {
  display: block;
  max-width:100%;
  max-height:100%;
}
header,footer {
  flex: 0 0 20px;
  background-color:#aaa;
}
<div id="box">
<header>
  this is the header text
</header>
<div id="container">
  <img src="http://cimus.eu/editions/(mi)chile/webcimus/hd/001.jpg"/>
</div>
<footer>
  this is the footer text
</footer>
</div>
Andy Tschiersch
  • 3,716
  • 1
  • 17
  • 24