Piotr Berebecki Piotr Berebecki - 1 month ago 7
CSS Question

How to reduce responsively the height of images in the flexbox layout to fit window height?

I've developed the following layout using the Flexbox CSS model:



html {
box-sizing: border-box;
overflow-y: none;
}
*,
*:before,
*:after {
margin: 0;
padding: 0;
box-sizing: inherit;
}
#all {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
background: #03a9f4;
}
#app {
width: 500px;
background: #ffffff;
border: solid 6px yellow;
}
header {
display: flex;
justify-content: center;
align-items: center;
border: solid 4px blue;
}
#header-para-container {
flex: 1;
}
#header-image-container {
flex: 0.6;
background: #888;
}
#header-image-container > img {
display: block;
width: 100%;
height: auto;
}
section {
display: flex;
flex-wrap: wrap;
border: solid 4px tomato;
}
figure {
display: flex;
justify-content: center;
align-items: center;
flex-basis: 50%;
border: solid 4px green;
}
figure > img {
max-width: 80%;
height: auto;
}

<div id="all">
<div id="app-container">
<div id="app">
<header>
<div id="header-para-container">
<p>Hello, this is CSS flexbox layout. Thank you for visiting this page.</p>
</div>
<div id="header-image-container">
<img src="http://placekitten.com/g/300/300" />
</div>
</header>
<section id="grid-images">
<figure>
<img src="http://placekitten.com/g/300/300" />
</figure>
<figure>
<img src="http://placekitten.com/g/300/300" />
</figure>
<figure>
<img src="http://placekitten.com/g/300/300" />
</figure>
<figure>
<img src="http://placekitten.com/g/300/300" />
</figure>
</section>
</div>
</div>
</div>





https://jsfiddle.net/petebere/fsLpw1vb/.

Would you know how to reduce responsively the height of the images and the main display element (in yellow frame) as the viewport height decreases?

The idea is that the element in yellow frame should be always fully visible and there should be no need for vertical scrolling.

At the moment when the viewport height drops, the height of the yellow container stays constant. This is probably because the browser wants to keep the sizes that I've applied to the container of the header image:

#header-image-container {
...
flex: 0.6;
...
}


and to the containers of the grid images:

figure {
...
flex-basis: 50%;
...
}


I've produced this graphic to show what I'm trying to achieve when the window height is reduced:

enter image description here

Answer

The images aren't scaling because they aren't bound by a fixed height on their immediate containers.

For example, the first image in the layout (in the header section), has neither a parent (.header-image-container) nor a grandparent (header) with a defined height. Here's the actual code:

header {
  display: flex;
  justify-content: center;
  align-items: center;
  border: solid 4px blue;
}

#header-image-container {
  flex: 0.6;
  background: #888;
}

With the code above, the image has no need to be responsive. There is no height confinement.

Try this instead:

header {
  display: flex;
  justify-content: center;
  align-items: center;
  border: solid 4px blue;
  height: 20vh; /* NEW */
}

#header-image-container {
  flex: 0.6;
  background: #888;
  height: 100%; /* NEW */
}

#header-image-container > img {
  /* display: block; */
  /* width: 100%; */
  /* height: auto; */
  height: 100%; /* NEW */
}

revised demo

The same concept above applies to the #grid-images section:

section {
  display: flex;
  flex-wrap: wrap;
  border: solid 4px tomato;  
  height: 60vh; /* NEW */
}

figure {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-basis: 50%;
  border: solid 4px green;
  height: 50%; /* NEW */
}

figure > img {
  /* max-width: 80%; */
  /* height: auto; */
  height: 100%; /* NEW */
}

revised demo

Additional notes:

  1. In your original code you're trying to make your images responsive with width: 100%; height: auto (in the header section) and max-width: 80%; height: auto (in the grid section). This set-up (using percentage widths) is more suited for horizontal screen re-sizing. Your question seeks vertical re-sizing, so use percentage heights instead.

  2. In your original layout, you may have noticed that when you reduce the screen height, the layout disappears at the top of the screen, with no access via vertical scroll. This is a known issue with flexbox. The solution is to use margin: auto on the centered flex item, instead of justify-content: center; align-items: center on the flex container. Full details here: Can't scroll to top of flex item that is overflowing container