Сетка с высотой области просмотра и внутренним прокруткой - PullRequest
0 голосов
/ 07 февраля 2019

Я пытаюсь создать макет, который использует сетку, которая занимает весь видовой экран браузера (height: 100vh), а затем позволяет элементу div в одном из элементов сетки прокручиваться в измерении Y.

Вот пример кода.Есть три области сетки: заголовок в верхней части, левая навигация и область содержимого в правом нижнем углу.

Я пытаюсь сделать так, чтобы div внутри области содержимого (big-list), это единственное, что имеет вертикальную полосу прокрутки, а остальная часть пользовательского интерфейса остается на экране.

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 голосов
/ 07 февраля 2019

Вы можете применить высоту к .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>
0 голосов
/ 07 февраля 2019

Решение

Добавьте это к своему коду:

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

You 'мы пытаемся визуализировать вертикальную полосу прокрутки на элементе списка (.big-list), но у него нет ограничения по высоте.

Высоты, которые у вас есть для этого:

  1. 1fr (для строки, установленной .outer-container).Это даже не длина.Это распределение свободного пространства.Это не может вызвать переполнение.

  2. height: auto, что является высотой по умолчанию для элементов.Это не дает никаких ограничений, так как содержимое просто будет расширять контейнер.Так что это также не может вызвать переполнение.

Поскольку вы не хотите использовать фиксированные высоты, но хотите, чтобы элемент списка отображал полосу прокрутки, когда это необходимо, вы должнынемного подлыйТем не менее, это беспроигрышный.Браузер получает то, что хочет.Вы получаете то, что хотите.

Добавьте это к своему коду:

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

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

Итак, вы превращаете родителя элемента списка (#content) в гибкий контейнер дляединственная цель включения flex-grow для дочернего элемента (.big-list).

Вы задаете небольшую фиксированную высоту для элемента списка (height: 1px).Это удовлетворяет условию, необходимому для переполнения.Браузер получает то, что хочет.

Затем, чтобы элемент списка заполнил оставшуюся высоту, вы добавляете flex-grow: 1.Вы получаете то, что хотите.

Поскольку height эквивалентно flex-basis в гибком контейнере в направлении столбца, вы можете упростить до:

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