具有视口高度和内部滚动div的网格 [英] Grid with viewport height and inner scrolling div

查看:80
本文介绍了具有视口高度和内部滚动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: 150pxmax-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生效,块级容器 必须具有设置的高度(heightmax-height)或white-space设置为nowrap.

In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap.

您正在尝试在列表元素(.big-list)上呈现垂直滚动条,但是它没有高度限制.

You're trying to render a vertical scrollbar on your list element (.big-list), but it doesn't have a height limitation.

为此设置的高度为:

  1. 1fr(对于该行,由.outer-container设置).这甚至不是长度.这是自由空间的分布.这不会触发溢出.

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆