具有视口高度和内部滚动div的网格 [英] Grid with viewport height and inner scrolling div
问题描述
我正在尝试创建一个布局,该布局使用一个占据整个浏览器视口(height: 100vh
)的网格,然后允许其中一个网格项中的div沿Y维度滚动.
I'm trying to create a layout that uses a grid that takes up the entire browser viewport (height: 100vh
) and then allows a div within one of the grid items to scroll in the Y dimension.
这是一些示例代码.共有三个网格区域:顶部的标题,左侧的导航栏和右下方的内容区域.
Here's some example code. There are three grid areas: a header across the top, a left nav, and a content area in the lower right.
我正在尝试使其在内容区域(big-list
)内如此分隔,这是唯一具有垂直滚动条的东西,而其余的UI则停留在屏幕上.
I'm trying to make it so div inside the content area (the big-list
), is the only thing with a vertical scrollbar, and the rest of the UI stays on the screen.
body {
margin: 0;
}
.outer-grid {
display: grid;
height: 100vh;
grid-template-columns: 180px 1fr;
grid-template-rows: min-content 1fr;
}
.top-bar {
grid-column-start: 1;
grid-column-end: 3;
border-bottom: 1px solid rgb(200, 200,200);
}
.header {
font-weight: bold;
margin: 8px;
}
.left-nav {
overflow-y: scroll;
padding: 8px;
border-right: 1px solid rgb(200, 200, 200);
}
#content {
padding-left: 8px;
padding-right: 8px;
}
#search {
width:100%;
}
.big-list {
overflow-y: scroll;
}
.big-list div {
padding: 8px 0;
border-top: 1px solid rgb(230,230,230);
}
<body>
<div class="outer-grid">
<div class="top-bar">
<div class="header">Header</div>
</div>
<div class="left-nav">
<div>Nav 1</div>
<div>Nav 2</div>
<div>Nav 3</div>
</div>
<div id="content">
<input id='search' type="text"/>
<div class='big-list'>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Last Row </div>
</div>
</div>
</div>
</body>
推荐答案
解决方案
将此添加到您的代码中:
Solution
Add this to your code:
#content {
display: flex; /* new */
flex-direction: column; /* new */
}
.big-list {
flex: 1 0 1px; /* new */
}
.outer-grid {
display: grid;
height: 100vh;
grid-template-columns: 180px 1fr;
grid-template-rows: min-content 1fr;
}
.top-bar {
grid-column-start: 1;
grid-column-end: 3;
border-bottom: 1px solid rgb(200, 200, 200);
}
.header {
font-weight: bold;
margin: 8px;
}
.left-nav {
/* overflow-y: scroll; */ /* removed */
padding: 8px;
border-right: 1px solid rgb(200, 200, 200);
}
#content {
display: flex; /* new */
flex-direction: column; /* new */
padding-left: 8px;
padding-right: 8px;
}
#search {
width: 100%;
}
.big-list {
flex: 1 0 1px; /* new */
overflow-y: auto; /* adjusted */
}
.big-list div {
padding: 8px 0;
border-top: 1px solid rgb(230, 230, 230);
}
body {
margin: 0;
}
<div class="outer-grid">
<div class="top-bar">
<div class="header">Header</div>
</div>
<div class="left-nav">
<div>Nav 1</div>
<div>Nav 2</div>
<div>Nav 3</div>
</div>
<div id="content">
<input id='search' type="text" />
<div class='big-list'>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Row ... </div>
<div> Last Row </div>
</div>
</div>
</div>
要发生溢出,内容必须使容器溢出.
For an overflow to occur, content must overflow the container.
要使内容溢出容器,容器必须具有大小限制.通常,它是固定长度或最大长度,例如width: 150px
或max-height: 50vh
.
For content to overflow the container, the container must have a size limitation. Usually it's a fixed or maximum length, such as width: 150px
or max-height: 50vh
.
来自 MDN :
为了使
overflow
生效,块级容器 必须具有设置的高度(height
或max-height
)或white-space
设置为nowrap
.
In order for
overflow
to have an effect, the block-level container must have either a set height (height
ormax-height
) orwhite-space
set tonowrap
.
您正在尝试在列表元素(.big-list
)上呈现垂直滚动条,但是它没有高度限制.
You're trying to render a vertical scrollbar on your list element (.big-list
), but it doesn't have a height limitation.
为此设置的高度为:
-
1fr
(对于该行,由.outer-container
设置).这甚至不是长度.这是自由空间的分布.这不会触发溢出.
1fr
(for the row, set by.outer-container
). This isn't even a length. It's a distribution of free space. This cannot trigger an overflow.
height: auto
,这是元素的默认高度.这没有任何限制,因为内容只会继续扩展容器.因此,这也不会触发溢出.
height: auto
, which is the default height on elements. This doesn't provide any limitation, as content will simply keep expanding the container. So this cannot trigger an overflow, either.
由于您不想使用固定的高度,而是希望list元素在必要时呈现滚动条,因此您必须有点偷偷摸摸.不过,这是双赢的.浏览器将获得所需的内容.您得到了想要的东西.
Since you don't want to use fixed heights, but want the list element to render a scrollbar when necessary, you've got to be a bit sneaky. Still, it's a win-win. The browser gets what it wants. You get what you want.
将此添加到您的代码中:
Add this to your code:
#content {
display: flex;
flex-direction: column;
}
.big-list {
height: 1px;
flex-grow: 1;
}
因此,您要做的是将列表元素的父级(#content
)转换为flex容器,其唯一目的是在子级(.big-list
)上启用flex-grow
.
So what you're doing is turning the list element's parent (#content
) into a flex container for the sole purpose of enabling flex-grow
on the child (.big-list
).
您在列表元素(height: 1px
)上设置了一个很小的固定高度.这满足了溢出所需要的条件.浏览器将获得所需的内容.
You set a tiny fixed height on the list element (height: 1px
). This satisfies the condition needed for an overflow. The browser gets what it wants.
然后,要使列表元素填充剩余的高度,请添加flex-grow: 1
.您得到了想要的东西.
Then, for the list element to fill remaining height, you add flex-grow: 1
. You get what you want.
由于在列方向flex容器中height
等效于flex-basis
,因此您可以简化为:
Since height
is equivalent to flex-basis
in a column-direction flex container, you can simplify to:
flex: 1 0 1px /* flex-grow, flex-shrink, flex-basis */
这篇关于具有视口高度和内部滚动div的网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!