CSS 网格-自动高度行,调整内容大小

我在一个网格中嵌套了两个网格。不幸的是,右侧嵌套网格 .grid-3设置了行的高度,因此左右两个网格的高度相同,额外的空间由类 .right在 div 之间共享。如何设置右边嵌套网格的行以调整内容的大小,使它们与左边嵌套行的高度相同?

div {
border: 1px dotted black;
}
.grid-2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: auto;
}


.grid-3 {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-rows: auto;
}


.left {
background-color: red;
}
 

.right {
background-color: green;
}
<div class="grid-2">
<div class="grid-2">
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
</div>
<div class="grid-3">
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
</div>
</div>

158649 次浏览

You can try minmax(min-content, max-content) ref

div {
border: 1px dotted black;
}
.grid-2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: minmax(min-content, max-content);
}


.grid-3 {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-rows: minmax(min-content, max-content);
}


.left {
background-color: red;
}
 

.right {
background-color: green;
}
<div class="grid-2">
<div class="grid-2">
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
</div>
<div class="grid-3">
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
</div>
</div>

You can also use only max-content or min-content

div {
border: 1px dotted black;
}
.grid-2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: max-content; /* min-content*/
}


.grid-3 {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-rows: max-content; /* min-content*/
}


.left {
background-color: red;
}
 

.right {
background-color: green;
}
<div class="grid-2">
<div class="grid-2">
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
<div class="left">L</div>
</div>
<div class="grid-3">
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
<div class="right">R</div>
</div>
</div>

By default grid items stretch to all grid cell area. So you have this options here if you want grid's height to fit content:

  • Set alignment for all items using align-items for grid container (default value is align-items: stretch). So just set align-items: start for grid-2. Demo:

    div {
    border: 1px dotted black;
    }
    
    
    .grid-2 {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    align-items: start;
    }
    
    
    .grid-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    }
    
    
    .left {
    background-color: red;
    }
     
    
    .right {
    background-color: green;
    }
    <div class="grid-2">
    <div class="grid-2">
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    </div>
    <div class="grid-3">
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    </div>
    </div>

  • Set alignment for grid items individually using align-self (default value is align-self: stretch). So just set align-self: start for grid-3. Demo:

    div {
    border: 1px dotted black;
    }
    
    
    .grid-2 {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    }
    
    
    .grid-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    align-self: start;
    }
    
    
    .left {
    background-color: red;
    }
     
    
    .right {
    background-color: green;
    }
    <div class="grid-2">
    <div class="grid-2">
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    </div>
    <div class="grid-3">
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    </div>
    </div>

  • Set alignment for grid items individually using margin property with auto values. Auto margins for grid cell take all available space in any direction. So just set margin-bottom: auto for grid-3. Demo:

    div {
    border: 1px dotted black;
    }
    
    
    .grid-2 {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    }
    
    
    .grid-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    margin-bottom: auto;
    }
    
    
    .left {
    background-color: red;
    }
     
    
    .right {
    background-color: green;
    }
    <div class="grid-2">
    <div class="grid-2">
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    <div class="left">L</div>
    </div>
    <div class="grid-3">
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    <div class="right">R</div>
    </div>
    </div>

If you want right grid to take all parent vertical space but make its cells to fit content use this answer.

You can also try grid-auto-rows: fit-content(1em);. Of course, use whatever sizing makes sense for you. I also tried the approach described by Temani (minmax(min-content, max-content)) and the results were identical when rendering my HTML.

According to Elad Schechter - Medium,

The fit-content function accepts one param, the maximum value. ... The fit-content() function is similar to using the minmax() function, with a minimum value of 0. One key difference: The minmax() is more likely to occupy the max space allowed, while the fit-content does not occupy any more space than necessary.

Your needs will determine whether fit-content is more appropriate than using minmax and vice-versa.