Flexbox: shrink image to fit

醉酒当歌 提交于 2020-08-19 04:29:49

问题


I am trying to design a page with the following properties that will be used as digital signage:

  • Page height is viewport height (100vh) so that scrolling is impossible
  • Page is arranged into full-width rows
  • All rows but the last are static (have pre-defined content)
  • Last row (which will contain an image slideshow) should fill the remaining space in the viewport.

Here is what I have so far:

body {
  margin: 0;
}
div#container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
div.red {
  height: 100px;
  background-color: red;
  flex: 0 0 auto;
}
div.blue {
  height: 150px;
  background-color: blue;
  flex: 0 0 auto;
}
div.green {
  background-color: green;
  flex: 0 1 auto;
}
img {
  max-height: 100%;
}
<div id="container">
  <div class="red"></div>
  <div class="blue"></div>
  <div class="green">
    <img src="http://lorempixel.com/200/300/">
  </div>
</div>

https://jsfiddle.net/62qqnx3m/6/

Clearly this is not working because flex is not shrinking the image div to the right size.

I can remove the flex: 0 0 auto from the first two divs, but then they shrink instead.

How can I force the green div/image to take up exactly what space remains, no more, no less?

So if a taller image was supplied, it would shrink even more to fit.

And if an image is smaller than the available space, it should simply display, with the background div still filling the available space.

It seems like max-height:100% would be great for this, but that also does not work.

Furthermore, I have seen examples of how to do this horizontally (which I also need, but am having less trouble with), but I can't figure out how to translate that into vertical scaling.


回答1:


You can set the position of the green block to relative and the position of the image to absolute. Also make sure the height of the green block is set to 100% (to take the rest of the height of the page).

This should fix the problem:

body {
  margin: 0;
}

div#container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

div.red {
  height: 100px;
  background-color: red;
  flex: 0 0 auto;
}

div.blue {
  height: 150px;
  background-color: blue;
  flex: 0 0 auto;
}

div.green {
  background-color: green;
  flex: 0 1 auto;
  position: relative;
  height: 100%;
}

img
{
  max-height: 100%;
  position: absolute;
}
<body>
  <div id="container">
    <div class="red"></div>
    <div class="blue"></div>
    <div class="green"><img src="http://lorempixel.com/200/300/"></div>
  </div>
</body>



回答2:


So here's what we know:

  • The page height is 100vh
  • The first row is static (height: 100px)
  • The second row is static (height: 150px)
  • The third row, which contains images, should fill the remaining height

I think the solution lies in basic math:

100vh - 100px - 150px = height of third row

Instead of this in your code:

div.green {
    background-color: green;
    flex: 0 1 auto;
}

img {
    max-height: 100%;
}

Try this:

div.green {
    background-color: green;
    flex: 1 1 auto;
}

img {
    height: calc(100vh - 250px);
}

body {
  margin: 0;
}
div#container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
div.red {
  height: 100px;
  background-color: red;
  flex: 0 0 auto;
}
div.blue {
  height: 150px;
  background-color: blue;
  flex: 0 0 auto;
}
/* 
div.green {
  background-color: green;
  flex: 0 1 auto;
}
img
{
  max-height: 100%;
}
*/

div.green {
  background-color: green;
  flex: 1 1 auto;
}
img {
  height: calc(100vh - 250px);
}
<div id="container">
  <div class="red"></div>
  <div class="blue"></div>
  <div class="green">
    <img src="http://lorempixel.com/200/300/">
  </div>
</div>

revised fiddle




回答3:


I just change the img class and add to class .green min-height: 100%; Additionally the image is responsive now with that code.

body {
  margin: 0;
   
}

div#container {
  display: flex;
  flex-direction: column;
  height: 100vh;  
}

div.red {
  height: 100px;
  background-color: red;
  flex: 0 0 auto;
}

div.blue {
  height: 150px;
  background-color: blue;
  flex: 0 0 auto;
}

div.green {
  background-color: green;
  flex: 0 1 auto;
   min-height: 100%;
}

.green img {
  max-width: 100%;
  display: block;
  margin: 0 auto;
  height: auto;
}
<body>
  <div id="container">
    <div class="red"></div>
    <div class="blue"></div>
    <div class="green"><img src="http://lorempixel.com/200/300/"></div>
  </div>
</body>



回答4:


Try this fiddle: https://jsfiddle.net/ez4pf8wp/

Added this to the img class:

img {
   max-height: 100%;
   height: 100%;
   display: block;
   margin: 0;
}


来源:https://stackoverflow.com/questions/39812393/flexbox-shrink-image-to-fit

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!