skip to Main Content

The difference between auto-fill and auto-fit is that the latter collapses the empty columns.

But after by adding an item that spans all columns auto-fit breaks and starts behaving like auto-fill. I can’t find this behavior anyway in the specs. I fill it’s just bad implementation.

Is there a way to prevent it?

.auto-fit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr))
}

.auto-fill {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}

div > div {
  aspect-ratio: 1;
  background-color: gold;
  border: 1px solid black;
}

h2 {
  grid-column: 1 / -1;
}
<h1>repeat(auto-fit)</h1>
<div class="auto-fit">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<h1>repeat(auto-fill)</h1>
<div class="auto-fill">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<h1>repeat(auto-fit) with</h1>
<div class="auto-fit">
  <h2>element spanning all columns</h2>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

2

Answers


  1. The behavior you’re observing with auto-fit collapsing empty columns when a spanning element is added is indeed expected according to the CSS Grid specification. When using auto-fit, the grid will create as many tracks as possible while maintaining the defined minimum and maximum sizes. When a spanning element is added, it effectively occupies one or more tracks, causing the grid to adjust by collapsing the empty columns.

    If you want to prevent this behavior and keep the grid tracks consistent even when spanning elements are added, you can use a combination of auto-fill, minmax, and max-content for the grid-template-columns property.

    .auto-fill {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(100px, max-content));
    }
    <h1>repeat(auto-fill) with</h1>
    <div class="auto-fill">
      <h2>element spanning all columns</h2>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </div>

    By using max-content, you ensure that each track will be as wide as necessary to fit the widest content within it. This prevents the collapsing of empty columns when a spanning element is added.

    Login or Signup to reply.
  2. Because of you break the natural behavior of the auto-fit keyword value with the span keyword. When you spaning an element, the grid will create some new columns and other grid-items will behave as if there were some columns there.

    If you want to distribute this space between other items, you can follow this way:
    Note: I changed some HTML elements to make the changes clearer.

    .auto-fit {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
      /* I recommend this declaration instead of the above,
    because it has more natural behavior. 
    It behaves like the `flex: 1` declaration.
     */
      /* grid-template-columns: repeat(auto-fit, minmax(min(100px, 100%), 1fr)); */
    
    }
    
    .auto-fill {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));  
    }
    
    div > div {
      /* aspect-ratio: 1; */
      min-height: 100px;
      background-color: gold;
      border: 1px solid black;
    }
    
    .div-test {
      grid-column: 1 / -1;
      background-color: green;
    }
    .inner-container {
      grid-column: 1 / -1;
      display: flex;
    }
    
    .inner-container > * {
      flex: 1;
    }
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>replit</title>
      <link href="style.css" rel="stylesheet" type="text/css" />
    </head>
    
    <body>
    <h1>repeat(auto-fit)</h1>
    <div class="auto-fit">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </div>
    
    <h1>repeat(auto-fill)</h1>
    <div class="auto-fill">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </div>
    
    <h1>repeat(auto-fit) with</h1>
    <div class="auto-fit">
      <!-- <h2>element spanning all columns</h2> -->
      <div class="div-test"></div>
      <div class="inner-container">
        <div></div>
        <div></div>
        <div></div>
        <div></div>
      </div>
    </div>
    </body>
    
    </html>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search