代码之家  ›  专栏  ›  技术社区  ›  Rob N

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

  •  1
  • Rob N  · 技术社区  · 7 年前

    我正在尝试创建一个布局,使用占据整个浏览器视口的网格( 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 回复  |  直到 7 年前
        1
  •  7
  •   Michael Benjamin William Falcon    7 年前

    解决方案

    将以下内容添加到代码中:

    #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: 150px max-height: 50vh .

    从…起 MDN :

    为了 overflow 要产生效果,请使用块级别容器 必须有一个设定的高度( height max-height )或者 white-space 开始 nowrap .

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

    你为它设定的高度是:

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

    2. height: auto ,这是图元上的默认高度。这并没有提供任何限制,因为内容只会不断扩展容器。所以这也不会触发溢出。

    由于您不想使用固定高度,但希望列表元素在必要时呈现滚动条,因此您必须有点狡猾。不过,这是双赢的。浏览器得到它想要的东西。你得到你想要的。

    将以下内容添加到代码中:

    #content {
      display: flex;
      flex-direction: column;
    }
    
    .big-list {
      height: 1px;
      flex-grow: 1;
    }
    

    所以你要做的就是把列表元素的父元素( #content )放入flex容器中,仅用于 flex-grow 在孩子身上( .大名单 ).

    在列表元素上设置一个微小的固定高度( height: 1px ).这满足溢出所需的条件。浏览器得到它想要的东西。

    然后,为让列表元素填充剩余高度,添加 flex-grow: 1 .你得到你想要的。

    自从 身高 相当于 flex-basis 在柱方向柔性容器中,可以简化为:

    flex: 1 0 1px /* flex-grow, flex-shrink, flex-basis */
    
        2
  •  0
  •   Hiren Vaghasiya    7 年前

    你可以将高度应用于 .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>
    推荐文章