css grid repeat(auto-fit) breaks when an item span all columns. Is there a way to prevent it?

44 Views Asked by At

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>

1

There are 1 best solutions below

0
a.donmez04 On

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>