Search code examples
htmlcsscss-gridminmax

How does CSS allocate space for columns in a grid where each column width is defined by a minmax() function with fixed values?


I hope the question title makes sense. If not, here is a specific scenario:

Let's say we have an element like so:

main {
  width: 500px;
  display: grid;
  grid-template-columns: minmax(200px, 300px) minmax(250px, 255px) minmax(100px, 150px);
}

So this main element is a grid that has 500px of width to work with. How is the width of each individual column determined?

Is it a greedy approach where the first column takes 300px, the second takes up 200px and the last gets 0px?

But if we assign column widths based on the min values then the first would take up 200px, the second 250px, leaving 50px for the last column to take up.

I'm hoping to understand how space for each column is allocated in this particular scenario, so as to have a thorough understanding of CSS grid if I will end up using it going forward.

Thanks in advance!


Solution

  • Let's start with the trivial case where you have a width equal to 550px. Each element will logically use its minimum value and since they cannot get smaller you will have the same configuration from 0px to 550px which will result in an overflow.

    The other case is when you have a width equal to or bigger than 705px where all your elements will use their maximum value.

    Between 550px and 705px, the browser will try to divide the space equally while respecting the minmax boundaries. Each item has a base size (the minimum value) and a growth limit (the maximum value).

    Let's take an example of 600px. All the columns start at their base size:

    200px | 250px | 100px
    

    Then the browser will increase all the sizes at the same time and once a column reaches its grow limit we stop.

    We will first reach the point

    205px | 255px | 105px
    

    And we stop for the second column because it reaches the maximum value but we continue for the other columns. Notice that we still have 35px of free space and this space can be divided between the first and third column without reaching their max value to end with:

    222.5px | 255px | 122.5px
    

    main {
      width: 600px;
      display: grid;
      grid-template-columns: minmax(200px, 300px) minmax(250px, 255px) minmax(100px, 150px);
      outline: 1px solid;
      height: 200px;
    }
    
    main>* {
      outline: 1px solid red;
    }
    <main>
      <div></div>
      <div></div>
      <div></div>
    </main>

    Let's try with 650px. We follow the same logic (I let you do it alone) and we end with:

    247.5px | 255px | 147.5px
    

    main {
      width: 650px;
      display: grid;
      grid-template-columns: minmax(200px, 300px) minmax(250px, 255px) minmax(100px, 150px);
      outline: 1px solid;
      height: 200px;
    }
    
    main>* {
      outline: 1px solid red;
    }
    <main>
      <div></div>
      <div></div>
      <div></div>
    </main>