具有视口高度和内部滚动div的网格

时间:2019-02-07 01:15:48

标签: html css css3 css-grid grid-layout

我正在尝试创建一个布局,该布局使用一个占据整个浏览器视口(height: 100vh)的网格,然后允许其中一个网格项中的div沿Y维度滚动。

这是一些示例代码。共有三个网格区域:顶部的标题,左侧的导航栏和右下方的内容区域。

我正在尝试使其在内容区域(big-list)内如此分隔,这是唯一具有垂直滚动条的东西,其余的UI仍留在屏幕上。

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>

2 个答案:

答案 0 :(得分:4)

解决方案

将此添加到您的代码中:

#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>


说明

要使内容溢出,内容必须使容器溢出。

要使内容溢出容器,容器必须具有大小限制。通常,它是固定长度或最大长度,例如width: 150pxmax-height: 50vh

来自MDN

  

为了使overflow生效,块级容器   必须具有设置的高度(heightmax-height)或white-space设置为nowrap

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

您要设置的高度是:

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

  2. height: auto,这是元素的默认高度。这没有任何限制,因为内容只会继续扩展容器。因此,这也不会触发溢出。

由于您不想使用固定的高度,而是希望list元素在必要时呈现滚动条,因此您必须有点偷偷摸摸。不过,这是双赢的。浏览器将获得所需的内容。您得到了想要的东西。

将此添加到您的代码中:

#content {
  display: flex;
  flex-direction: column;
}

.big-list {
  height: 1px;
  flex-grow: 1;
}

因此,您要做的是将列表元素的父级(#content)转换为flex容器,其唯一目的是在子级(flex-grow)上启用.big-list

您在列表元素(height: 1px)上设置了一个很小的固定高度。这满足了溢出所需的条件。浏览器将获得所需的内容。

然后,要使列表元素填充剩余的高度,请添加flex-grow: 1。您得到了想要的东西。

由于在列方向flex容器中height等效于flex-basis,因此您可以简化为:

flex: 1 0 1px /* flex-grow, flex-shrink, flex-basis */

答案 1 :(得分:0)

您可以对.big-list.left-nav减去高度的height: calc(100vh - 51px); overflow-y: auto;header应用于search的高度

.big-list {
    overflow-y: scroll;
    height:calc(100vh - 56px);
}

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: auto;
    padding: 8px;
    border-right: 1px solid rgb(200, 200, 200);
    height: calc(100vh - 51px);
}
#content {
    padding-left: 8px;
    padding-right: 8px;
}
#search {
    width:100%;
}
.big-list {
    overflow-y: scroll;
    height:calc(100vh - 56px);
}
.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>