title: Is it possible to use a fixed min and max width for columns in a CSS grid which are repeating and wrappable?
body: <p>I'd like to set up a CSS layout where a container contains a fixed number of flexible width tiles with the following properties:</p>
  <ul>
  <li>Spacing in between tiles is fixed and consistent</li>
  <li>They can expand in size between a fixed min and max width, but should all be the same width irrespective of their content. In the example below I'm using 100px min width and 200px max width.</li>
  <li>They should wrap onto multiple lines if at their minimum width they don't all fit horizontally in the container.</li>
  <li>If the container is much larger they should not expand larger than their maximum fixed width, should remain centered in the container and the space between them should not expand.</li>
  </ul>
  <p>Perhaps it's not possible with pure CSS, but it feels like it should be! There's a minimal example below, which I'll detail here:</p>
  <p><a href="https://jsfiddle.net/vztskh6f/1/" rel="nofollow noreferrer">https://jsfiddle.net/vztskh6f/1/</a></p>
  <h1>Option 1: CSS Grid</h1>
  <p>This seems to be the best candidate, seeing as we always want tile widths to be consistent. In order to get columns to wrap I believe you need to use the <code>repeat()</code> syntax and <code>repeat(auto-fit, ...)</code> seems best for this use case. The obvious solution seems to be to use <code>repeat(auto-fit, minmax(100px, 200px))</code>. <em>However, this does not work</em> tiles always remain at <code>200px</code> irrespective of the width of the container. In every other way this is behaving as desired:</p>
  <pre><code>.gridContainer {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(100px, 200px));
    padding: 10px;
    gap: 10px;
    justify-items: center;
    justify-content: center;
  }
  
  .child {
    width: 100%;
    height: 30px;
    background: #0f0;
    text-align: center;
  }
  </code></pre>
  <p>It could be possible to enforce the desired spec with Option 1, by using <code>grid-template-columns: repeat(auto-fit, minmax(100px, 1fr))</code> and then setting a computed <code>max-width</code> on the container and forcing it to center too, but it feels like this should be possible with CSS Grid alone?</p>
  <h1>Option 2: Flexbox</h1>
  <p>Wrapping is much simpler to achieve with flexbox and using the <code>flex</code> on a child means we can easily set flexible tiles with min and max widths. However once a child wraps onto a second line, it will obviously expand to its max width and will be inconsistent with other tiles:</p>
  <pre><code>.flexContainer {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
  }
  
  .child {
    height: 30px;
    background: #0f0;
    text-align: center;
    min-width: 100px;
    max-width: 200px;
    // this seems to create consistent widths better than flex: 1 1 100px;
    flex: 1 1 0;
    // could use gap if it wasn't for Safari
    margin: 0 5px 10px;
  }
  </code></pre>
  <h1>Screenshots</h1>
  <p>The first row is the grid layout, the second is the flex layout, you can see these are behaving nicely at full width, not expanding beyond their max widths with consistent spacing between them:</p>
  <p><a href="https://i.stack.imgur.com/VnONV.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/VnONV.png" alt="Flex and Grid layouts full width" /></a></p>
  <p>As the container shrinks you can see that the grid layout items are not shrinking with it, but immediately wrap. flex layout behaves nicely:</p>
  <p><a href="https://i.stack.imgur.com/FdwYm.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FdwYm.png" alt="Flex and Grid layouts container shrinking" /></a></p>
  <p>As the container continues to shrink, the flex starts to wrap in the desired place, but immediately the tile on the next row expands to its max width:</p>
  <p><a href="https://i.stack.imgur.com/Ro0BT.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Ro0BT.png" alt="Flex and Grid layouts container small" /></a></p>