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:
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:
(3) But look what happens when grid-row-gap
is 10px:
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
:
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
align-items: center
(same layout as in the question)
(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:
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:
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.
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:
- Instead of
auto
orfr
, trygrid-auto-rows: min-content
- Remove the
height: 250px
on the container; this sets the height of the container to the height of the content (i.e.,height: auto
) - 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;
, orpadding-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 newdiv
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
Anchor <A> Tags Not Working in Chrome When Using #
Height: 100% for <Div> Inside <Div> with Display: Table-Cell
Difference Between Onblur and Onchange Attribute in HTML
How to Use an <H2> Tag </H2> Inside a <P></P> in The Middle of a Text
Twitter Bootstrap: Center Pills
HTML Submit-Button: Different Value/Button-Text
How to Add The Text "On" and "Off" to Toggle Button
How to Center Content in a Bootstrap Column
Why Is a Trailing Punctuation Mark Rendered at The Start with Direction:Rtl
How to Specify Model to a Nginclude Directive in Angularjs
Why Does 'Transform' Break 'Position: Fixed'
How to Change The Style of a <Select>'s <Optgroup> Label
HTML - Two Tables Horizontally Side by Side
Scrolling to an Anchor Using Transition/CSS3
Prevent a Child Element from Overflowing Its Parent in Flexbox