Home > Software design >  How do I prevent a CSS grid blowout when using gap?
How do I prevent a CSS grid blowout when using gap?

Time:08-17

Consider this simple layout:

<div >
  <div ></div>
  <div ></div>
</div>
.container{
  display: grid;
  grid-template-columns: repeat(100, minmax(0, 1fr));
  gap: 0;
  max-width: 100px;
}

.box {
  height: 100px;
  min-width: 0px;
  grid-column: span 30;
}

The result is what you'd expect. Two 30px wide children inside a 100px wide container.

Working grid layout

If you then change gap: 0; to gap: 2px;, the layout does something unexpected. The grid children grow much wider than they should, and blow out of the container element.

enter image description here

A strange detail is that gap:1px; also works fine. Only gaps > 1px cause the issue.

Here's a demo:

.container {
  display: grid;
  grid-template-columns: repeat(100, minmax(0, 1fr));
  gap: 0;
  max-width: 100px;
  margin-bottom: 20px;
  padding: 5px;
  background-color: LightGrey;
}

.container1 {
  gap: 0px;
}

.container2 {
  gap: 1px;
}

.container3 {
  gap: 2px;
}

.box {
  height: 100px;
  min-width: 0px;
  grid-column: span 30;
}

.box1 {
  background-color: DarkBlue;
}

.box2 {
  background-color: CornflowerBlue;
}
No gap, no problems
<div >
  <div ></div>
  <div ></div>
</div>

1px gap, still good
<div >
  <div ></div>
  <div ></div>
</div>

2px gap, ?!?!
<div >
  <div ></div>
  <div ></div>
</div>

Does anyone have an explanation for this strange behavior, and even better, a way to prevent it? Thanks!

Edit: Thanks to @Jhecht, I've found a good solution. Posted as an answer below.

CodePudding user response:

Thanks to the comment from @Jhecht I've figured out a good answer for my case.

The issue here is that a 2px gap * 100 columns = 200px, which is greater than the max-width of the container. I need a flexible solution that deals with arbitrary container widths and gap sizes, given a 100 column grid.

The answer is this nice little bit of modern CSS: gap: min(2px, 1%);

If the container is wide enough, the pixel value will be applied. Otherwise a 1% gap will be applied, which is the maximum size a gap can be given 100 columns.

Here's a working demo:

.container {
  display: grid;
  grid-template-columns: repeat(100, minmax(0, 1fr));
  gap: min(2px, 1%);
  max-width: 100px;
  margin-bottom: 20px;
  padding: 5px;
  background-color: LightGrey;
}

.box {
  height: 100px;
  min-width: 0px;
  grid-column: span 30;
}

.box1 {
  background-color: DarkBlue;
}

.box2 {
  background-color: CornflowerBlue;
}
<div >
  <div ></div>
  <div ></div>
</div>

CodePudding user response:

I got your query, You mentioned grid-template-columns: repeat(100, minmax(0, 1fr));

The problem is that a 2px gap * 100 columns = 200px, which is greater than the max-width of the container. That is why we can see overflow happens in container3. For its solution:

Either you can make columns repeat to some small no like

  • grid-template-columns: repeat(5, minmax(0, 1fr));

    and inner boxes to

  • grid-column: span 1;.

Or you can change in the gap like:

  • gap: min(2px, 1%);

So that you can get the expected output.

Here's a working demo for the first scenario:

.container{
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0;
  max-width: 100px;
  margin-bottom: 20px;
  padding: 5px;
  background-color: LightGrey;
}

.container1{
  gap: 0px;
}

.container2{
  gap: 1px;
}

.container3{
  gap: 2px;
}

.box {
  height: 100px;
  min-width: 0px;
  grid-column: span 1;
}

.box1 {
  background-color: DarkBlue;
}

.box2 {
  background-color: CornflowerBlue;
}
No gap, no problems
<div >
  <div ></div>
  <div ></div>
</div>

1px gap, still good
<div >
  <div ></div>
  <div ></div>
</div>

2px gap, ?!?!
<div >
  <div ></div>
  <div ></div>
</div>

CodePudding user response:

in Container you mention repeat(100, minmax(0, 1fr)) inside box grid-column: span 30;

change this into

.container{
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0;
    max-width: 100px;
    margin-bottom: 20px;
    padding: 5px;
    background-color: LightGrey;
}
.box {
    height: 100px;
    min-width: 0px;
    /* grid-column: span 30; */ remove this line
}
  • Related