问题
I made a design using css grids which gave me unexpected space between rows. I reproduced my issue with the following code:
main {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
article {
background: red;
}
.item1 {
height: 30px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}
.item2 {
height: 100px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 3;
}
.item3 {
height: 300px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 3;
grid-row-end: 4;
}
.item4 {
height: 490px;
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 5;
}
.item5 {
height: 160px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 4;
grid-row-end: 6;
}
.item6 {
height: 520px;
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 5;
grid-row-end: 7;
}
.item7 {
height: 300px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 6;
grid-row-end: 7;
}
<main>
<article class="item1"></article>
<article class="item2"></article>
<article class="item3"></article>
<article class="item4"></article>
<article class="item5"></article>
<article class="item6"></article>
<article class="item7"></article>
</main>
Here you can see extra gap on top of the bottom items.
I found a similar question -- Why does CSS Grid layout add extra gaps between cells? -- where the extra gap was caused by figures and solved using display: flex
on the figures, but that didn't work for me.
Any idea?
EDIT:
My example was misleading, here is a closer-to-the-real-problem version:
main {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
article {
background: red;
}
article div {
background: blue;
}
.item1 {
grid-column-start: 1;
grid-column-end: span 1;
grid-row-start: 1;
grid-row-end: span 1;
}
.item1 div {
height: 30px;
}
.item2 {
grid-column-start: 1;
grid-column-end: span 1;
grid-row-start: 2;
grid-row-end: span 1;
}
.item2 div {
height: 100px;
}
.item3 {
grid-column-start: 1;
grid-column-end: span 1;
grid-row-start: 3;
grid-row-end: span 1;
}
.item3 div {
height: 300px;
}
.item4 {
grid-column-start: 2;
grid-column-end: span 1;
grid-row-start: 1;
grid-row-end: span 4;
}
.item4 div {
height: 490px;
}
.item5 {
grid-column-start: 1;
grid-column-end: span 1;
grid-row-start: 4;
grid-row-end: span 2;
}
.item5 div {
height: 160px;
}
.item6 {
grid-column-start: 2;
grid-column-end: span 1;
grid-row-start: 5;
grid-row-end: span 2;
}
.item6 div {
height: 520px;
}
.item7 {
grid-column-start: 1;
grid-column-end: span 1;
grid-row-start: 6;
grid-row-end: span 1;
}
.item7 div {
height: 300px;
}
<main>
<article class="item1"><div></div></article>
<article class="item2"><div></div></article>
<article class="item3"><div></div></article>
<article class="item4"><div></div></article>
<article class="item5"><div></div></article>
<article class="item6"><div></div></article>
<article class="item7"><div></div></article>
</main>
Here you can see extra gap in red. The heights on the contained div
are just here to simulate the real content of the articles, so they can't be modified in the real example (they are left to default in the real code). Based on the pre-edit answers, I tried grid-auto-rows
property, but it didn't solve the problem.
回答1:
You have a grid container with three explicit columns and 10px gutters:
main {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
There are no rows defined. All rows are implicit and take content height (because a default setting of a grid container is grid-auto-rows: auto).
Inside this container are seven grid items that are positioned using line-based placement.
Let's break this down to individual pieces.
Item 1
.item1 {
height: 30px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}
Simple enough. Item 1 spans across the first column and first row. It is 30px in height, which sets the row height.
Item 2
.item2 {
height: 100px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 3;
}
Again, pretty straightforward. Item 2 spans across the first column and second row. It is 100px in height, which sets the row height.
Item 3
.item3 {
height: 300px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 3;
grid-row-end: 4;
}
Like the two items above, Item 3 is clear and simple. It spans across the first column and third row. It is 300px in height, which sets the row height.
Now it starts to get a bit tricky...
Item 4
.item4 {
height: 490px;
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 5;
}
Item 4 is set to span a total of four rows:
grid-row-start: 1 / grid-row-end: 5
It has a height of 490px.
But items 1, 2 & 3 are set to span a total of three rows:
grid-row-start: 1 / grid-row-end: 4
...and their total height is: 430px (30px + 100px + 300px)
Therefore, Item 4 creates a new row with a height of 30px (490px - 430px - 30px grid row gaps).
Item 5
.item5 {
height: 160px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 4;
grid-row-end: 6;
}
Item 5 has a height of 160px and is set to span two rows. It starts at the fourth row (which was created by Item 4) and creates a new fifth row.
Because row heights are set to auto
, each row receives an equal distribution of the height of the grid item, as defined in the spec for grid areas that cover multiple tracks. This makes rows 4 and 5 each 80px tall.
Important: Notice how Item 5 equal height rows expand row 4, which is now spaced away from its original position at the bottom of Item 4. The first gap has been created.
Item 6
.item6 {
height: 520px;
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 5;
grid-row-end: 7;
}
Item 6 is set to start at row 5. As explained above (see Important), row 5 can no longer be fitted to Item 4 because of grid-auto-rows: auto
on the Item 5 grid area. This results in a 50px gap above Item 6.
80px height of row 4 - 30px excess of Item 4 = 50px
But now Item 6 adds to the 80px height of row 5 created by Item 5. The second gap has been created.
Item 7
.item7 {
height: 300px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 6;
grid-row-end: 7;
}
The height of the last two rows is determined by the following three factors:
- the height of Item 5, which is 80px in row 5
- the height of Item 6, which is 520px, which combines with the height of row 5 and spans two rows
- the height of Item 7, which is 300px and spans 1 row
For the same reason that grid row line 5 is spaced away from Item 4, grid row line 6 spaces away from Item 5: The auto
row height is distributing the height of Item 6 among the rows it covers.
One Solution
Instead of setting heights to Grid Items, consider setting grid-auto-rows
to something like 10px. Then use the span
keyword to created the grid areas you want.
So instead of this...
main {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
.item5 {
height: 160px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 4;
grid-row-end: 6;
}
consider this:
main {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 10px; /* new */
grid-column-gap: 10px;
grid-row-gap: 10px;
}
.item5 {
/* height: 160px; */
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 4; /* this would have to be adjusted, as well */
grid-row-end: span 16; /* new */
}
This approach is covered here: CSS-only masonry layout but with elements ordered horizontally
回答2:
apparently it's not the same issue ( in Why does CSS Grid layout add extra gaps between cells? )
the thing is you're specifying the height
of the column forcing it not to fill the remaining and messing up the grid
, since you're specifying where it should start
and end
in grid-column
and grid-row
, setting the height
to auto
for the right column items will fix your issue,
i believe the reason why the grid
is behaving like this is because you didn't set the grid-template-rows
for the grid
, the rows are having the heights of their content on the first columns,
i think you should not set the heights of your grid-items
and use grid-template-rows
, and if you're not satisfied with heights with height:auto
, maybe you should consider reworking your grid-row-start
and grid-row-end
i hope this solves your issue or at least gives you an idea on how to fix it.
main {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
article {
display: flex;
background: red;
}
.item1 {
height: 30px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}
.item2 {
height: 100px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 3;
}
.item3 {
height: 300px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 3;
grid-row-end: 4;
}
.item4 {
height: auto;
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 5;
}
.item5 {
height: 160px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 4;
grid-row-end: 6;
}
.item6 {
height: auto;
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 5;
grid-row-end: 7;
}
.item7 {
height: 300px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 6;
grid-row-end: 7;
}
<main>
<article class="item1"></article>
<article class="item2"></article>
<article class="item3"></article>
<article class="item4"></article>
<article class="item5"></article>
<article class="item6"></article>
<article class="item7"></article>
</main>
回答3:
The gap come from a miscalculation of heights you are setting to the containers. You should mind the 10px gutters your element element is spanning through.
To keep it fluid, you might use min-height
instead height
and use grid-template-rows
or grid-auto-rows
to somehow set a min-height
to the rows.
You can also set no heights at all and let the boxes and rows adapt their size to the content they hold.
Test with min-height
and grid-template-rows
(grid-auto-rows
, see other answer).
main {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows:repeat(auto-fill, 4em);/* min-height of 4em if row is empty*/
grid-column-gap: 10px;
grid-row-gap: 10px;
}
article {
display: flex;
background: red;
}
.item1 {
/* it will be at least 4em of height*/
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}
.item2 {
min-height:180px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 3;
}
.item3 {
min-height:80px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 3;
grid-row-end: 4;
}
.item4 {
min-height:150px;
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 5;
}
.item5 {
min-height:450px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 4;
grid-row-end: 6;
}
.item6 {
min-height:240px;
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 5;
grid-row-end: 7;
}
.item7 {
min-height:160px;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 6;
grid-row-end: 7;
}
/* see and name me */
article:before{
content:attr(class);
font-size:2em;
}
<main>
<article class="item1"></article>
<article class="item2"></article>
<article class="item3"></article>
<article class="item4"></article>
<article class="item5"></article>
<article class="item6"></article>
<article class="item7"></article>
</main>
Or do not set any heights and let the layout grow from its content:
main {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
article {
display: flex;
background: red;
/* to deal with 'lorem ipsum' content added */
flex-flow:column;
padding:0.5em;
}
.item1 {
/* it will be at least 4em of height*/
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}
.item2 {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 3;
}
.item3 {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 3;
grid-row-end: 4;
}
.item4 {
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 5;
}
.item5 {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 4;
grid-row-end: 6;
}
.item6 {
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 5;
grid-row-end: 7;
}
.item7 {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 6;
grid-row-end: 7;
}
<main>
<article class="item1"><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p></article>
<article class="item2"><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p></article>
<article class="item3"><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p></article>
<article class="item4"><h1>HTML Ipsum Presents</h1>
<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>
<h2>Header Level 2</h2>
<ol>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
</ol>
</article>
<article class="item5"><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p></article>
<article class="item6"><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p></article>
<article class="item7"></article>
</main>
来源:https://stackoverflow.com/questions/49636862/remove-wide-gaps-in-css-grid