Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
405 views
in Technique[技术] by (71.8m points)

html - Why does CSS Grid layout add extra gaps between cells?

Can’t figure out why CSS grid layout adds an unwanted extra space to content around the vertical cells, though margin and padding are zeroed out:

images positioned with CSS grid

.grid {
  display: grid;
  grid-template-columns: 13fr 11fr 4fr 20fr;
  grid-auto-rows: 12fr;
  grid-gap: 4px;
  align-items: center;
}

.grid figure {
  outline: 1px solid red;
  margin: 0;
  padding: 0;
}


.grid figure img {
  margin: 0;
  padding: 0;
  width: 100%;
  display: block;
}

.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;
}
<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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

enter image description here

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:

enter image description here


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

enter image description here

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:

enter image description here

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

enter image description here

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

enter image description here


(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:

enter image description here

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...