skip to Main Content
  • Row 1 should always be the height of its content + 1 share of the remaining available space
  • Row 2 should always be the height of its content
  • Row 3 should always be the height of its content + 2 shares of the remaining available space
.container{

  height: 150px;
  width: 75px;

  resize: vertical;
  overflow: auto;

  display: grid;
  grid-template-rows: 1fr min-content 2fr;
  grid-template-columns: 100%;

  & :nth-child(1){
    background-color: pink;
  }
  & :nth-child(2){
    background-color: aqua;
  }
  & :nth-child(3){
    background-color: lime;
  }

}
<div class="container">

  <div>Row 1</div>
  <div>Row 2</div>
  <div>Row 3</div>

</div>

Row 2 works as I want, but Row 1 and Row 3 does not work as I want. If you resize the container and make it smaller, you will see that when Row 1 reaches its smallest height, Row 3 will be assigned all the remaining space. I don’t want that to happen, but I always want this to be true:

Is what I want to achieve possible to achieve with CSS grid? And if so, how? In my mind, I want something like calc(min-content + 1fr) for Row 1, but that doesn’t work

2

Answers


  1. Better to work with flexbox than with an explicit grid if you want size to be based on height of content:

    .container {
      min-height: 150px;
      width: 75px;
      display: flex;
      flex-flow: column nowrap;
      & :nth-child(1) {
        background-color: pink;
        flex-grow: 1;
      }
      & :nth-child(2) {
        background-color: aqua;
      }
      & :nth-child(3) {
        background-color: lime;
        flex-grow: 2;
      }
    }
    <div class="container">
      <div>Row 1</div>
      <div>Row 2</div>
      <div>Row 3</div>
    </div>

    Flex algorithm will try and fit everything based off content size, and then the remaining available space will be filled at the rates described by flex-grow

    Login or Signup to reply.
  2. You are almost there, however you just need to know how to use min and max in CSS to achieve this. A grid system with min/max should solve the problem.

    Here is the reference I used: min()_max()

    This code snippet should guide you.

    .container {
      height: 150px;
      width: 75px;
      resize: vertical;
      overflow: auto;
      display: grid;
      grid-template-rows: minmax(min-content, auto) min-content minmax(min-content, auto);
      grid-template-columns: 100%;
    }
    
    .container > div {
      display: flex;
      flex-direction: column;
    }
    
    .container > div:nth-child(1) {
      background-color: pink;
      flex: 1 1 auto; /* one row sharing the remaining space */
    }
    
    .container > div:nth-child(2) {
      background-color: aqua;
    }
    
    .container > div:nth-child(3) {
      background-color: lime;
      flex: 2 1 auto; /* the two rows remaining space */
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search