Pull to refresh

Использование CSS Flexbox для позиционирования блоков на странице

Website development *CSS *HTML *
Sandbox

Задача


В блоке на странице требуется разместить два вложенных блока таким образом, чтобы один блок имел максимальную высоту, а второй — занимал все оставшееся в родительском блоке свободное место по высоте. Причем, в случае, если контент не помещается в блок, добавлять ему скролл.

image


Реализация


При реализации данной задачи было принято решение использовать CSS Flexbox.
Для начала следует решить задачу без учета контента, т.е. с двумя пустыми дочерними блоками:

image

Как это работает


Родительскому блоку (на рисунке обозначен зеленым цветом) задан display: flex; и flex-direction: column; для задания направления контента. Дочерним блокам заданы стили flex: 0 0 auto; для блока, для которого известна высота, и flex: 1 0 auto; для блока, который бодет растягиваться на все свободное место. «1» для второго блока в данном случае означает «жадность», т.е. более жадный блок занимает больше места, чем менее жадный, а т.к. в данном случае у менее жадного задана высота (может быть задана максимальная высота), то более жадный блок занимает все свободное место.

Добавим контент в нижний блок


Для добавления скролла тут достаточно указать overflow: auto;

image

Добавим контент в верхний блок


Тут так просто, как с нижним блоком, не выйдет. Все потому, что flex учитывает ее и высоту контента.

image

Чтобы решить эту проблему, контент необходимо спозиционировать абсолютно (position: absolute;) и задать ему свойства top, right, bottom, left равными нулю (чтобы растянуть его по размерам блока)

image

Теперь блок занимает нужный нам размер, однако контент вылазит из него. Для решения этой проблемы необходимо родительскому для контента блоку задать position: relative; overflow: auto;

image

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

image

Результат (HTML):
<div class="container">
  <div class="first-child">
    <div class="first-content">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua
    </div>    
  </div>
  <div class="second-child">
    <div class="second-content">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua
    </div>
  </div>
</div>


Результат (SCSS)
.container {
  display: flex;
  flex-direction: column;
  width: 150px;
  height: 200px;
  background-color: #A5D6A7;
  
  .first-child {    
    flex: 1 0 auto;
    position: relative;
    overflow: auto;
    width: 125px;
    box-sizing: border-box;
    background-color: #90CAF9;
    
    .first-content {
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      padding: 5px;
    }
  }
  
  .second-child {
    flex: 0 0 auto;
    width: 125px;
    max-height: 75px;
    padding: 5px;
    box-sizing: border-box;
    overflow: auto;
    background-color: #CE93D8;
  }
}


P.S. Работающий пример можно посмотреть тут
Tags:
Hubs:
Total votes 20: ↑13 and ↓7 +6
Views 13K
Comments Comments 14