Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flexbox: shrink image to fit

Tags:

html

css

flexbox

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.

like image 719
baum Avatar asked Oct 01 '16 23:10

baum


People also ask

How do I shrink a photo in flexbox?

You can easily shrink an image by using the flex-wrap property in CSS and it specifies whether flex items are forced into a single line or wrapped onto multiple lines. The flex-wrap property allows enabling the control direction in which lines are stacked.

How do I shrink my flex box?

The flex-shrink CSS property sets the flex shrink factor of a flex item. If the size of all flex items is larger than the flex container, items shrink to fit according to flex-shrink .

Does flexbox work on images?

CSS flexbox has the potential to wrap, align, and justify items in a container. This makes it handy for creating a responsive layout in a grid-like structure. In this tutorial, we used flexbox to create three responsive image gallery projects that look amazing on all devices.

How do I reduce the size of an image in a div?

To auto-resize an image or a video to fit in a div container use object-fit property. It is used to specify how an image or video fits in the container. object-fit property: This property is used to specify how an image or video resize and fit the container.


2 Answers

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>
like image 174
Dekel Avatar answered Oct 18 '22 10:10

Dekel


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

like image 26
Michael Benjamin Avatar answered Oct 18 '22 10:10

Michael Benjamin