CSS Grid gutter is causing columns to overflow, how do I force the column width to conform

1.3k Views Asked by At

I'm trying to create a fairly simple 12 column CSS Grid framework and allow the nesting of grids.

.grid {
    grid-template-columns: repeat($grid-column-count, minmax(0, 1fr));
    column-gap: 2rem;
}

I'm currently having an issue where the fractional columns are being pushed out of the nested grid container when increasing the gutter width, no matter what content is in it.

I've tried setting the minmax value to 0 when declaring the columns but it still insists on expanding. I know this is because the width of the gutters adds up to more than the content, but is there a way to force it down without using the overflow property?

Columns are being pushed by the gutter and/or content:

Columns are being pushed by the gutter and/or content

...when columns should accommodate gutter instead:

...when columns should accommodate gutter instead

Codepen

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

.container {
  display: grid;
  grid-template-columns: [left-gutter-start] auto [left-gutter-end] minmax(0, 960px) [main-content-end] auto [right-gutter-end];
  overflow-wrap: break-word;
}

.container>.grid {
  grid-column-start: left-gutter-end;
  grid-column-end: main-content-end;
}

.container>.grid.grid-breakout {
  grid-column-start: left-gutter-start;
  grid-column-end: right-gutter-end;
}

.grid {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  -webkit-column-gap: 2rem;
  column-gap: 2rem;
  grid-column-end: span 12;
}

.grid .grid {
  -webkit-column-gap: 2rem;
  column-gap: 2rem;
}

.grid .col-1 {
  grid-column-end: span 1;
}

.grid .col-2 {
  grid-column-end: span 2;
}

.grid .col-3 {
  grid-column-end: span 3;
}

.grid .col-4 {
  grid-column-end: span 4;
}

.grid .col-5 {
  grid-column-end: span 5;
}

.grid .col-6 {
  grid-column-end: span 6;
}

.grid .col-7 {
  grid-column-end: span 7;
}

.grid .col-8 {
  grid-column-end: span 8;
}

.grid .col-9 {
  grid-column-end: span 9;
}

.grid .col-10 {
  grid-column-end: span 10;
}

.grid .col-11 {
  grid-column-end: span 11;
}

.grid .col-12 {
  grid-column-end: span 12;
}

.grid .col-end {
  grid-column-end: -1;
}

.grid .colstart-start {
  grid-column-start: 1;
}

.grid .colstart-2 {
  grid-column-start: 3;
}

.grid .colstart-3 {
  grid-column-start: 4;
}

.grid .colstart-4 {
  grid-column-start: 5;
}

.grid .colstart-5 {
  grid-column-start: 6;
}

.grid .colstart-6 {
  grid-column-start: 7;
}

.grid .colstart-7 {
  grid-column-start: 8;
}

.grid .colstart-8 {
  grid-column-start: 9;
}

.grid .colstart-9 {
  grid-column-start: 10;
}

.grid .colstart-10 {
  grid-column-start: 11;
}

div[class*="col-"] {
  text-align: left;
  background-color: orange;
  font-size: 12px;
  font-family: sans-serif;
}

div[class*="col-"]:before {
  content: attr(class);
  display: inline-block;
  margin: 4px;
}

.container[class*="col-"]:before {
  display: none;
}

div[class*="col-"] div[class*="col-"] {
  background: lightgreen;
}

div[class*="col-"] div[class*="col-"]:after {
  content: " (nested)";
  display: inline-block;
  margin: 4px;
}

.grid {
  row-gap: 1rem;
}

.grid .grid {
  background: green;
}

.grid-breakout {
  background: red;
}

.container {
  -webkit-column-gap: 1rem;
  column-gap: 1rem;
  row-gap: 1rem;
  margin-bottom: 1rem;
}
<div class="container">
  <div class="grid">

    <div class="col-4"></div>
    <div class="col-4">
      <div class="grid">
        <div class="col-12"></div>
        <div class="col-3"></div>
        <div class="col-9"></div>
        <div class="col-2"></div>
        <div class="col-10"></div>
        <div class="col-1"></div>
        <div class="col-11"></div>
      </div>
    </div>
    <div class="col-4"></div>
    <div class="col-4"></div>
  </div>

  <div class="grid">
    <div class="col-6">
      <p>This is what I would want to happen...</p>
      <div class="grid">
        <div class="col-12"></div>
        <div class="col-3"></div>
        <div class="col-9"></div>
        <div class="col-2"></div>
        <div class="col-10"></div>
        <div class="col-1"></div>
        <div class="col-11"></div>
      </div>
    </div>
    <div class="col-6">
      <div class="grid">
        <div class="col-4"></div>
        <div class="col-8"></div>
      </div>
    </div>
  </div>
</div>

2

There are 2 best solutions below

1
Azul On
.main {
    display: grid;
    grid-gap: 10px;
    grid-template-columns: repeat(12, 1fr);
    margin: 0 auto;
    width: 100%;
    max-width: 1280px;
}

.one, .two, .three, .four, .five, .six,
.seven, .eight, .nine, .ten, .eleven, .twelve {
    grid-column-end: span 12;
}

.nested {
    display: grid;
    grid-gap: 10px;
    grid-template-columns: repeat(12, 1fr);
}

.merge-two-rows { grid-row-end: span 2 }
.merge-three-rows { grid-row-end: span 3 }
.merge-four-rows { grid-row-end: span 4 }
.merge-five-rows { grid-row-end: span 5 }
.merge-six-rows { grid-row-end: span 6 }

@media only screen and (min-width: 481px) {
    .one { grid-column-end: span 1 }
    .two { grid-column-end: span 2 }
    .three { grid-column-end: span 3 }
    .four { grid-column-end: span 4 }
    .five { grid-column-end: span 5 }
    .six { grid-column-end: span 6 }
    .seven { grid-column-end: span 7 }
    .eight { grid-column-end: span 8 }
    .nine { grid-column-end: span 9 }
    .ten { grid-column-end: span 10 }
    .eleven { grid-column-end: span 11 }
}

Resource: Smart 12 Column Grid with Nesting

0
Ignacio Bustos On

Short answer.

Bear in mind, that for any given grid, you should never have gaps that multiplied by the columns will have bigger size than the container grid even when the columns has no content.

In other words: gap * columns(0width) < gridWidth otherwise, it will overflow.

Try to reduce the gap for inner grids from 2rem to 1rem for instance and your example will work