Search code examples
htmlcssimagelayoutflexbox

CSS Layout: Mobile, Vertical Layout, Header (fixed height), Footer (fixed height). How to fill remaining space with img, constrained on height & width


Layout: Mobile, Vertical Layout, Header (fixed height), Footer (fixed height). How to fill remaining space with img, constrained on height & width

This is a very common layout for me on iOS. Trying to understand how to do it in CSS.

Here's what I'm trying:

Using flexbox with flex-direction column Setting height of header and footer (or can be done with flex-basis) flex-shrink: 0 for header and footer so they don't shrink flex-shrink: 1 on the image container so it shrinks if needed Setting max-width and max-height to 100% on image object-fit: scale-down so it keeps the aspect ratio of the image (this means there will be horizontal bars or vertical bars)

Issue: the image shrinks to fit the width, but should shrink even more than that to fit the available vertical space

HTML

<div class='container'>
  <div class='header'>
    Header
  </div>
  <div class='content'>
    <div class='image-container'>
      <img class="cat" src="https://jngnposwzs-flywheel.netdna-ssl.com/wp-content/uploads/2019/05/Transparent-OrangeWhiteCat-764x1024.png"/>
    </div>
  </div>
  <div class='footer'>
    Footer
  </div>
</div>

CSS

.container {
  background-color: #aaa;
  height: 400px;
  width: 175px;
  display: flex;
  flex-direction: column;
  border: 2px solid blue;
}

.box {
  border: 2px solid black;
  display: flex;
  justify-content: center;
  align-items: center;
}

.box1 {
  height: 100px;
  flex-shrink: 0;
}

.box2 {
  flex-shrink: 1;
}

.cat {
  max-width: 100%;
  max-height: 100%;
  object-fit: scale-down;
  border: 2px solid orange;
}

.box3 {
  height: 100px;
  flex-shrink: 0;
}

https://codepen.io/jeffrey-robert/pen/yLbNVZp


Solution

  • If you use object-fit, then the trick is to set to img :height:0;min-height:100%;width:100% and it should fill the flex child boxe, the child boxe will require flex-grow:1; too to fill the remaing space.

    .container {
      background-color: #aaa555;
      height: 400px;
      width: 175px;
      display: flex;
      flex-direction: column;
      border: 2px solid blue;
    }
    
    .box {
      border: 2px solid black;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .box1 {
      height: 100px;
      flex-shrink: 0;
    }
    
    .box2 {
      flex:1 1 auto;
    }
    
    .cat {
      width: 100%;
      height:0;
      min-height:100%;
      object-fit: scale-down;
      border: 2px solid orange;
    }
    
    .box3 {
      height: 100px;
      flex-shrink:1;
    }
    <div class="container">
      <div class="box box1">
        1
      </div>
      <div class="box box2">
        <img class="cat" src="https://jngnposwzs-flywheel.netdna-ssl.com/wp-content/uploads/2019/05/Transparent-OrangeWhiteCat-764x1024.png"/>
      </div>
      <div class="box box3">
        3
      </div>
    </div>