What is the logic behind this unexpected minmax(1px, 1fr)

Asked this on SO, but I think it is mistakenly closed as a duplicate. I thought I should give it a try here.


In this HTML structure which is placed inside the <body> element (demo here):

    <div class="grid-1">
    <header>
      <a href="/">Home</a>
    </header>
    <main>
      <article>
        <h1>Test</h1>
        <h2 id="overview">Overview</h2>
        <p>Lorem ipsum.</p>
        <div>
          <div>
            <pre><code>Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet
    Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet
    Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet, Lorem, Ipsum, Dolor, Sit, Amet
    </code></pre>
          </div>
        </div>
        <h2 id="conclusion">Conclusion</h2>
        <p>Lorem ipsum.</p>
      </article>
    </main>
    <footer>
      <a href="/">Home</a>
    </footer>

as you can see, the second child element (i.e. the <main> element) has a <pre> block with a few lengthy lines of code.

When this CSS stylesheet is applied to that HTML structure:

    html,
    body {
      margin: 0;
      padding: 0;
    }
    
    .grid-1 {
      margin-bottom: 50px;
      display: grid;
      grid-template-columns: 1fr 1fr 1fr;
    } 
    
    header {
      background: hsl(209, 36%, 90%);
      padding: 10px;
    }
    
    main {
      background: hsl(209, 36%, 80%);
      padding: 10px;
    }
    
    footer {
      background: hsl(209, 36%, 70%);
      padding: 10px;
    }
    
    pre {
      border: 1px solid black;
      padding: 10px;
      overflow-x: auto;
    }

The second column stretches to contain the entire lines of the <pre> block, making the overflow-x: auto; on the <pre> block to be effectively ignored, and pushes the third column out of the view and to the right (can’t post multiple images - screenshot here: https://i.stack.imgur.com/FXKUD.png).

However, if I change grid-template-columns: 1fr 1fr 1fr; to grid-template-columns: 1fr minmax(1px, 1fr) 1fr;, all three columns are assigned equal widths and the <pre> block’s overflow-x: auto; comes into effect (screenshot here: https://i.stack.imgur.com/YoSUa.png).

If I am not mistaken, in this scenario, minmax(1px, 1fr) should resolve to 1fr and make the second grid effectively identical to the first grid. Then why does it change the way the grid is rendered?

In summary, why do 1fr and minmax(1px, 1fr) act differently here?

I believe its because the default is min-width:auto which auto sizes the content inside. If you add the following to your second example the overflow will work.

.grid-2 > * { min-width: 1px }

In your first example the minmax is effectively doing the same thing. (This seems to be a similar issue to flexbox where inner items will not respect overflow unless you have used min-width:1px on the flex item.)

This article explains some of the points mentioned.

I still find grid a bit of a mystery and seems way too complex for simple layouts. A lot of grid demos are broken because people are using limited content.

2 Likes

A timely Css tricks article out today confirms my fix :).

The only thing they get wrong is that the min-with needs to be 1px and not zero for IE11 to play along.

3 Likes

Thanks for the explanation! :+1:

min-width: auto and “indefinitely sized” blocks are a bit confusing and unituitive at first.

The MDN docs on minmax are a bit vague too:

A function taking two parameters, min and max .

Each parameter can be a <length> , a <percentage> , a <flex> value, or one of the keyword values max-content , min-content , or auto .

If max < min, then max is ignored and minmax(min,max) is treated as min. As a maximum, a <flex> value sets the flex factor of a grid track; it is invalid as a minimum.

As you have pointed out, looks like the effect is no similar to:

width: <some value>;

but more like:

min-width: <some value>; 
max-width: <some other value>`
1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.