CSS Сетка - Как реализовать элементы сетки, которые не "растягивают" строку сетки и имеют контейнер с возможностью прокрутки - PullRequest
0 голосов
/ 13 февраля 2020

Моя задача:

Я хочу иметь сетку с фиксированным количеством столбцов (которое позже можно настроить с помощью javascript) и гибким количеством строк равной высоты.

Количество строк определяется количеством элементов сетки, которые являются UI карточками.

Эти карточки должны заполнять всю высоту соответствующих ячеек, но ДОЛЖНЫ не увеличивает высоту строки. Итак, в основном max-height = row-height assigned by grid

Тогда внутри этих карт у нас есть три типичные части: верхний колонтитул, основной текст и нижний колонтитул. Тело ДОЛЖНО иметь возможность прокрутки, если существует больше элементов списка, чем позволяет высота строки.

Я пытался реализовать это в stackblitz

https://stackblitz.com/edit/angular-3gkmtm

Чего я не понимаю, так это:

  1. Почему карты "растягивают" строку, когда появляется больше элементов
  2. Как создать секцию тела с возможностью прокрутки без использования вручную фиксированной высоты (как в примере я использую max-height)
  3. Почему при наличии более 3 строк переполняется

Пожалуйста, помогите!

<article>
  <section>
    <h2>Fixed Gird with scrollable cards</h2>
  </section>
  <section>
    <button (click)="onAdd()">Add</button>
    <button (click)="onRemove()">Remove</button>
  </section>
    <section class="remaining-height">
        <div class="grid-container">
      <div class="grid-item" *ngFor="let card of cards">
      <div class="card">
        <div class="card-header">Card #{{card}}</div>
        <div class="card-body card-flexible-scroll">
          <div class="list-item" *ngFor="let item of list">{{item}}</div>
        </div>
        <div class="card-footer">
            Some Footer
        </div>
      </div>
      </div>
        </div>
    </section>
</article>


article{
  display: flex;
  flex-direction: column;
  height: 100%;
}
.remaining-height{
  flex:1
}
.grid-container {
    display: grid;
    grid-gap: 0.5rem;
    height: 100%;
    grid-auto-rows: auto;
  grid-template-columns: repeat(5, auto);
}

.grid-item{
  display: flex;
  padding:24px;
}

.card{
  display: flex;
  flex-direction: column;
  width: 100%;
  height:100%;
  background:#ccc;
}
.card-body{
  .list-item{
    padding: 6px;
    background:#fcd3d3;
  }
   .list-item:nth-child(even){
  background:#efefef;
 } 
}
.card-flexible-scroll{
  flex:1;
  overflow-y:auto;
  max-height: 300px; // <= no max height
}

Angular Controller to generate cards and list items

```js
export class AppComponent {
  name = "Angular";
  cards = new Array(8).fill(0).map((_,idx)=>idx+1);
  list = new Array(30).fill(0).map((_,idx)=>idx+1);

  onAdd() {
    this.cards.push(this.cards.length + 1);
  }

  onRemove() {
    this.cards.pop();
  }
}

глобальный стиль

html , body{
  height: 100vh;
  overflow: hidden;
}

1 Ответ

2 голосов
/ 20 февраля 2020

Если я правильно понимаю, что вы пытаетесь сделать, вы хотите, чтобы тело карты занимало все доступное пространство строки между верхним и нижним колонтитулом и не заставляло карту быть больше, чем строка, если она содержит элементы. Этого можно добиться, добавив еще один div с абсолютным позиционированием внутри div тела карты, размер которого соответствует полной высоте тела, тогда элементы внутри будут правильно переполнены.

Вот измененный шаблон:

<article>
  <section>
    <h2>Fixed Gird with scrollable cards</h2>
  </section>
  <section>
    <button (click)="onAdd()">Add</button>
    <button (click)="onRemove()">Remove</button>
  </section>
    <section class="remaining-height">
        <div class="grid-container">
      <div class="grid-item" *ngFor="let card of cards">
      <div class="card">
        <div class="card-header">Card #{{card}}</div>
        <div class="card-body">
          <div class="card-flexible-scroll">
            <div class="list-item" *ngFor="let item of list">{{item}}</div>
          </div>
        </div>
        <div class="card-footer">
            Some Footer
        </div>
      </div>
      </div>
        </div>
    </section>
</article>

И обновленный CSS:

.card-body{
  .list-item{
    padding: 6px;
    background:#fcd3d3;
  }
   .list-item:nth-child(even){
    background:#efefef;
  }
  position: relative;
  flex:1;
}
.card-flexible-scroll{
  position: absolute;
  width: 100%;
  height: 100%;
  max-height: 100%;
  overflow-y: auto;
}

Я создал форк вашего StackBlitz , где вы можете увидеть, как он работает. Если это не то, что вы ищете, пожалуйста, объясните больше.

...