Why Does CSS Grid Layout Add Extra Gaps Between Cells

Why does CSS Grid layout add extra gaps between cells?

The vertical gaps are caused by the images not filling the vertical space in the grid items.

The problem is made worse with align-items: center on the container, which removes the align-items: stretch default.

Essentially, there are no gaps between grid items. They form a clean, neatly-arranged grid. But because the images are smaller than the items that contain them, and the items are then centered vertically with align-items, there are lots of gaps.

Here's a more detailed explanation, using Firefox's grid overlay tool for illustration:

(1) This is your grid when grid-row-gap and grid-column-gap are 0:

Sample Image

The red lines represent the grid items. The images are the content of the grid items. The dotted lines represent the grid lines.


(2) There is no problem when grid-column-gap is 10px:

Sample Image


(3) But look what happens when grid-row-gap is 10px:

Sample Image

The grid items (red lines) neatly wrap their content (the images). This happens only because the container is set to align-items: center.


(4) Now let's removes align-items: center (which restores the default stretch value) and keep grid-column-gap: 10px and grid-row-gap: 10px:

Sample Image

As you can see, the grid items (having red borders and yellow backgrounds) now expand full height. But the images, being smaller than the items, leave gaps.


(5) Here's the grid from (4) above without the indicators.

align-items: stretch

Sample Image

align-items: center (same layout as in the question)

Sample Image


(6) So the key is to get the images to fill the grid items.

One simple solution is to apply display: flex to the grid items, which will automatically assign align-items: stretch to the images, causing them to take full height.

And then, depending on how you want the images to look, you can use object-fit to manage their appearance.

Add this to your code:

.grid figure {
display: flex;
}

.grid figure img {
object-fit: cover; /* also try `contain` and `fill` */
}

With the adjustments above, the grid renders like this:

Sample Image

revised fiddle

.grid {  display: grid;  grid-template-columns: 13fr 11fr 4fr 20fr;  grid-auto-rows: repeat(12, 1fr);  grid-gap: 10px;  /* align-items: center; */}.grid figure {  border: 2px solid red;  margin: 0;  padding: 0;  background-color: yellow;  display: flex; /* new */}.grid figure img {  margin: 0;  padding: 0;  width: 100%;  display: block;  object-fit: cover; /* new */}.grid .gi13x12 {  grid-column-start: 1;  grid-column-end: 2;  grid-row-start: 1;  grid-row-end: 13;}.grid .gi11x6.one {  grid-column-start: 2;  grid-column-end: 3;  grid-row-start: 1;  grid-row-end: 7;}.grid .gi11x6.two {  grid-column-start: 2;  grid-column-end: 3;  grid-row-start: 7;  grid-row-end: 13;}.grid .gi4x4.one {  grid-column-start: 3;  grid-column-end: 4;  grid-row-start: 1;  grid-row-end: 5;}.grid .gi4x4.two {  grid-column-start: 3;  grid-column-end: 4;  grid-row-start: 5;  grid-row-end: 9;}.grid .gi4x4.three {  grid-column-start: 3;  grid-column-end: 4;  grid-row-start: 9;  grid-row-end: 13;}.grid .gi20x12 {  grid-column-start: 4;  grid-column-end: 5;  grid-row-start: 1;  grid-row-end: 13;}
* { box-sizing: border-box; }
<div class="grid"> <figure class="gi13x12">  <img itemprop="image" src="http://placehold.it/130x123"> </figure> <figure class="gi11x6 one">  <img itemprop="image" src="http://placehold.it/110x60"> </figure> <figure class="gi11x6 two">  <img itemprop="image" src="http://placehold.it/110x60"> </figure> <figure class="gi4x4 one">  <img itemprop="image" src="http://placehold.it/40x39"> </figure> <figure class="gi4x4 two">  <img itemprop="image" src="http://placehold.it/40x39"> </figure> <figure class="gi4x4 three">  <img itemprop="image" src="http://placehold.it/40x39"> </figure> <figure class="gi20x12">  <img itemprop="image" src="http://placehold.it/200x120"> </figure></div>

why CSS grid put extra gap?

So, i fixed my code with help of @CodeSpent. I added "border" to image with padding to item, not item img. Also change grid-column and grid-row gaps.

.wrapper {    display: grid;    grid-template-columns: 33.3% 33.3% 33.3%;    grid-template-rows: 33.3% 33.3% 33.3%;    margin: auto;    width: 80%;    grid-column-gap: 22px;    grid-row-gap: 10px;}
.item{ padding: 4px; background-color: black;}
.item img{ width: 100%; display: flex; }
.item:first-of-type{ grid-column: 1/3; grid-row: 1/3;}
<div class="wrapper">  <div class="item"><img src="http://static1.squarespace.com/static/5898e29c725e25e7132d5a5a/58aa11bc9656ca13c4524c68/58aa11e99656ca13c45253e2/1487540713345/600x400-Image-Placeholder.jpg?format=original" alt="Sample Image"></div>  <div class="item"><img src="http://static1.squarespace.com/static/5898e29c725e25e7132d5a5a/58aa11bc9656ca13c4524c68/58aa11e99656ca13c45253e2/1487540713345/600x400-Image-Placeholder.jpg?format=original" alt="Sample Image"></div>  <div class="item"><img src="http://static1.squarespace.com/static/5898e29c725e25e7132d5a5a/58aa11bc9656ca13c4524c68/58aa11e99656ca13c45253e2/1487540713345/600x400-Image-Placeholder.jpg?format=original" alt="Sample Image"></div>  <div class="item"><img src="http://static1.squarespace.com/static/5898e29c725e25e7132d5a5a/58aa11bc9656ca13c4524c68/58aa11e99656ca13c45253e2/1487540713345/600x400-Image-Placeholder.jpg?format=original" alt="Sample Image"></div>  <div class="item"><img src="http://static1.squarespace.com/static/5898e29c725e25e7132d5a5a/58aa11bc9656ca13c4524c68/58aa11e99656ca13c45253e2/1487540713345/600x400-Image-Placeholder.jpg?format=original" alt="Sample Image"></div>  <div class="item"><img src="http://static1.squarespace.com/static/5898e29c725e25e7132d5a5a/58aa11bc9656ca13c4524c68/58aa11e99656ca13c45253e2/1487540713345/600x400-Image-Placeholder.jpg?format=original" alt="Sample Image"></div></div>

Why CSS grid puts one more extra gap after the grid line ends?

As I couldn't see any problem I cleaned up your code a bit and filled all 6 rows. Instead of using the body I added a div which is the grid container. then removed margin and padding from body. This is my outcome:

grid-container with 6 columns + rows and 5 gaps

5 spacers vertically and 5 horizontally without additional space.

the html:

<div class="body">
<header>
<h1>PupSpa</h1>
</header>
<div id="banner">
<h2>2</h2>
<img src=>
</div>
<div id="description">
<p>3</p>
</div>
<div class="box address">
<img src="">
<h3>a</h3>
</div>
<div class="box hours">
<img src="">
<h4>b</h4>
</div>
<div class="box call_us">
<img src="">
<h4>c</h4>
</div>
<div class="box call_us">
<img src="">
<h4>c</h4>
</div>

<div id="banner">
<h2>2</h2>
<img src=>
</div>
<div id="description">
<p>3</p>
</div>
<div class="box address">
<img src="">
<h3>a</h3>
</div>
<div class="box hours">
<img src="">
<h4>b</h4>
</div>
<div class="box call_us">
<img src="">
<h4>c</h4>
</div>
<div class="box call_us">
<img src="">
<h4>c</h4>
</div>

<div id="banner">
<h2>2</h2>
<img src=>
</div>
<div id="description">
<p>3</p>
</div>
<div class="box address">
<img src="">
<h3>a</h3>
</div>
<div class="box hours">
<img src="">
<h4>b</h4>
</div>
<div class="box call_us">
<img src="">
<h4>c</h4>
</div>
<div class="box call_us">
<img src="">
<h4>c</h4>
</div>

<div id="banner">
<h2>2</h2>
<img src=>
</div>
<div id="description">
<p>3</p>
</div>
<div class="box address">
<img src="">
<h3>a</h3>
</div>
<div class="box hours">
<img src="">
<h4>b</h4>
</div>
<div class="box call_us">
<img src="">
<h4>c</h4>
</div>
<div class="box call_us">
<img src="">
<h4>c</h4>
</div>

<div id="banner">
<h2>2</h2>
<img src=>
</div>
<div id="description">
<p>3</p>
</div>
<div class="box address">
<img src="">
<h3>a</h3>
</div>
<div class="box hours">
<img src="">
<h4>b</h4>
</div>
<div class="box call_us">
<img src="">
<h4>c</h4>
</div>
<div class="box call_us">
<img src="">
<h4>c</h4>
</div>
</div>

css:

* {
padding: 0;
margin: 0;
box-sizing: border-box;
}

html {
font-size: 20px;
background-color: rgb(240, 236, 233);
font-family: 'Roboto', sans-serif;
margin: auto;
text-align: center;
}

html, body {
margin: 0;
padding: 0;
}

.body {
/*width: 80%;
margin:auto;*/
display: grid;
grid-template: 0.5fr 3fr 1fr 3fr 2fr 0.5fr / repeat(6, 1fr);
grid-gap: 1rem;
}

/* header */

header {
grid-area: 1 / 1 / 2 / 7;
height: auto;
display: grid;
}

working example: here

Spacing between rows wider than intended

It's hard to come to a solution here because there isn't enough data to reproduce the problem. But here's what it may be:

Because you haven't explicitly defined any rows in the grid, rows are implicitly added and their heights are set by default to grid-auto-rows: auto.

The auto and 1fr values will stretch to occupy empty space in the container.

So the gap you're seeing in your image #1 is not a gap between rows.

grid with 2 rows

The actual gap between rows is 5px, as set by your grid-row-gap rule.

There is an appearance of a gap between rows because the grid items are not filling the height of the row.

Look at it this way:

  • There are two rows.
  • The container is set to height: 250px.
  • The rows divide the height equally, so each row is 122.5px tall each (after subtracting the 5px grid row gap).
  • But the items inside those rows are set to height: 100px.
  • So there's a 22.5px gap between the bottom edge of the items and the bottom edge of the row.

When you have three rows, this free space is needed, and the rows close in.

Here are three potential solutions:

  1. Instead of auto or fr, try grid-auto-rows: min-content
  2. Remove the height: 250px on the container; this sets the height of the container to the height of the content (i.e., height: auto)
  3. Add align-content: start to the container

For more details see these posts:

  • Why does CSS Grid layout add extra gaps between cells?
  • Reduce space between rows in CSS Grid

Reduce space between elements in a css grid layout

grid-template-rows: repeat(5, 1fr); indicates that your grid has 5 rows of equal height. That's the height of the .experience-child container divided by 5.

There are many ways to reduce the whitespace between Job Role and Company Name:

  • You could reduce the height of the first row, by replacing it with e.g. grid-template-rows: 1em repeat(4, 1fr);

  • You could keep equal row height and move Job Role within its container with e.g. position: absolute; bottom: 0;, or padding-top: 1em;

  • You could place Company Name in the same container as Job Role by wrapping <p class="jobrole">Job Role</p><p class="company">Company Name</p> in a new div

Why does grid-gap cause an overflow?

Short Answer

Because the width of the columns plus the width of the gaps is greater than 100%.



Explanation

You have a 3-column grid container (.body):

grid-template-columns: 25% 50% 25%

The total width of those columns is 100%.

You're then adding gutters between the columns (and rows):

grid-gap: 10px

which is shorthand for:

grid-column-gap: 10px;
grid-row-gap: 10px;

So this becomes the width calculation:

25% + 50% + 25% + 10px + 10px

Hence,

100% + 20px > 100%, which results in an overflow condition

Note that the grid-*-gap properties apply only between grid items – never between items and the container. That's why we calculate two grid gaps, not four.

As a solution, instead of percentage units, try using fr units, which apply only to free space. This means that fr lengths are calculated after any grid-gap lengths are applied.

grid-template-columns: 1fr 2fr 1fr

div:not(.header):not(.body):not(.row) {
border: 1px solid grey;
}

.header {
margin-top: 20px;
display: grid;
grid-gap: 10px;
grid-template-areas: "header-left header-right-up" "header-left header-right-down";
grid-template-rows: 40px 40px;
grid-template-columns: minmax(50px, 200px) auto;
}

.header-left {
grid-area: header-left;
}

.header-right-up {
grid-area: header-right-up;
}

.header-right-down {
grid-area: header-right-down;
}

.body {
margin-top: 20px;
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* ADJUSTMENT */
grid-auto-rows: 80px;
grid-gap: 10px;
}

.row-left {}

.row-center {}

.row-right {}
<div class="header">
<div class="header-left">image</div>
<div class="header-right-up">content</div>
<div class="header-right-down">long content</div>
</div>

<div class="body">
<div class="row-left"></div>
<div class="row-center"></div>
<div class="row-right"></div>

<div class="row-left"></div>
<div class="row-center"></div>
<div class="row-right"></div>

<div class="row-left"></div>
<div class="row-center"></div>
<div class="row-right"></div>
</div>


Related Topics



Leave a reply



Submit