Как вписать блоки в страницу или в контейнер? Используйте css grid

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Я на днях обнаружил печальную вещь. Хотя стандарт css grid существует не первый год, многие до сих пор то ли не знают о нем, то ли не понимают, для чего он нужен. Я крайне редко вижу его практическое использование.

При этом существует задача, которая нормальным образом решается только через grid. Речь идет о вписывании верстки в родительский контейнер, будь то виджет или страница в целом. В итоге создание подобной верстки происходит либо с помощью костылей (если использовать обычную блочную верстку (когда ее уже пометят как obsolete?)), либо с помощью избыточного кода (если использовать flex). Давайте я покажу на пример, как это делать правильно.

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

<style>
      .root {
        width: 100%;
        height: 100%;
        background-color: yellow;        
      }
      .toolbar1 {
        background-color: green;
      }
      .main {
        background-color: grey;
      }
      .main-big-content {
        background-color: black;
        height: 2000px;
      }
      .toolbar2 {
        background-color: cyan;
      }
    </style>
    <div class="root">
      <div class="toolbar1">
        <button>button1</button>
      </div>
      <div class="main">
        <div class="main-big-content">
        </div>
      </div>
      <div class="toolbar2">
        <button>button1</button>
      </div>
    </div>

Посмотрим на результат:

Разумеется, все неправильно! Нижний тулбар не виден. Ну ок, добавим overflow к центру:

.main {
        background-color: grey;
        overflow: auto,
      }

Никакого эффекта.

Что ж, давайте использовать flex. Для этого придется усложнить код, добавив flex-direction: column, flex: 1 и т. д.:

      .root {
        width: 100%;
        height: 100%;
        background-color: yellow;   
        display: flex;
        flex-direction: column
      }
      .toolbar1 {
        background-color: green;
      }
      .main {
        background-color: grey;
        overflow: auto;
        flex: 1;
      }
      .main-big-content {
        background-color: black;
        height: 2000px;
      }
      .toolbar2 {
        background-color: cyan;
      }

Да что за ерунда? А, ну конечно. Body тоже скроллится. Ладно, добавим ограничителей:

html,body {
  height: 100%;
  padding: 0px;
  margin: 0px;
}

Да, теперь работает нормально. Вот только код стал, мягко говоря, немаленьким

html, body {
        height: 100%;
        padding: 0px;
        margin: 0px;
      }
      .root {
        width: 100%;
        height: 100%;
        background-color: yellow;   
        display: flex;
        flex-direction: column
      }
      .toolbar1 {
        background-color: green;
      }
      .main {
        background-color: grey;
        overflow: auto;
        flex: 1;
      }
      .main-big-content {
        background-color: black;
        height: 2000px;
      }
      .toolbar2 {
        background-color: cyan;
      }

А теперь представьте что у вас внутри каждого блока есть свои блоки, и если не добавлять в каждый display: flex, flex-direction: column и flex: 1, все разъедется! Но давайте не извращаться и все сделаем по-нормальному:

html, body {
        height: 100%;
        padding: 0px;
        margin: 0px;
      }
      .root {
        height: 100%;
        background-color: yellow;   
        display: grid;
        grid-template-rows: min-content auto min-content
      }
      .toolbar1 {
        background-color: green;
      }
      .main {
        background-color: grey;
        overflow: auto;
      }
      .main-big-content {
        background-color: black;
        height: 2000px;
      }
      .toolbar2 {
        background-color: cyan;
      }

Все просто, понятно и без лишнего кода.

Я вас еще не убедил? Давайте усложним задачу. И внутри нашей структуры сделаем еще одну такую же структуру. Для начала воспользуемся flex-ом:

html, body {
        height: 100%;
        padding: 0px;
        margin: 0px;
      }
      .root {
        width: 100%;
        height: 100%;
        background-color: yellow;   
        display: flex;
        flex-direction: column
      }
      .toolbar1 {
        background-color: green;
      }
      .main {
        background-color: grey;
        overflow: auto;
        flex: 1;
      }
      .main-big-content {
        background-color: black;
        height: 2000px;
      }
      .toolbar2 {
        background-color: cyan;
      }
    </style>
    <div class="root">
      <div class="toolbar1">
        <button>button1</button>
      </div>
      <div class="main">
          <div class="main-2">
            <div class="toolbar2-1">
               <button>button2-1</button>
            </div>
            <div class="main-big-content">
            </div>
            <div class="toolbar2-2">
                <button>button2-2</button>
            </div>
        </div>
      </div>
      <div class="toolbar2">
        <button>button1</button>
      </div>
    </div>

Сверху и снизу мы хотим по две кнопки. Естественно, мы этого не получаем:

Придется опять писать кучу кода про флексы...

html, body {
        height: 100%;
        padding: 0px;
        margin: 0px;
      }
      .root {
        width: 100%;
        height: 100%;
        background-color: yellow;   
        display: flex;
        flex-direction: column
      }
      .toolbar1, .toolbar2-1 {
        background-color: green;
      }
      .main {
        background-color: grey;
        flex: 1;
        display: flex;
        flex-direction: column;
        overflow: hidden;
      }
      .main-2 {
        background-color: grey;
        overflow: auto;
        flex: 1;
      }
      .main-big-content {
        background-color: black;
        height: 2000px;
      }
      .toolbar2, .toolbar2-2 {
        background-color: cyan;
      }

Все работает. Но посмотрите какой ценой!

Давайте перепишем на grid:

html, body {
        height: 100%;
        padding: 0px;
        margin: 0px;
      }
      .root {
        width: 100%;
        height: 100%;
        background-color: yellow;   
        display: grid;
        grid-template-rows: min-content auto min-content;
      }
      .toolbar1, .toolbar2-1 {
        background-color: green;
      }
      .main {
        background-color: grey;
        display: grid;
        grid-template-rows: min-content auto min-content;
        overflow: hidden;
      }
      .main-2 {
        background-color: grey;
        overflow: auto;
      }
      .main-big-content {
        background-color: black;
        height: 2000px;
      }
      .toolbar2, .toolbar2-2 {
        background-color: cyan;
      }

Все намного проще! А результат такой же:

А знаете в чем прикол? grid-template-rows на самом деле не нужны. Браузер умный, он сам справится:

html, body {
        height: 100%;
        padding: 0px;
        margin: 0px;
      }
      .root {
        width: 100%;
        height: 100%;
        background-color: yellow;   
        display: grid;
      }
      .toolbar1, .toolbar2-1 {
        background-color: green;
      }
      .main {
        background-color: grey;
        display: grid;
        overflow: hidden;
      }
      .main-2 {
        background-color: grey;
        overflow: auto;
      }
      .main-big-content {
        background-color: black;
        height: 2000px;
      }
      .toolbar2, .toolbar2-2 {
        background-color: cyan;
      }

Все равно все работает!

И да, вы конечно меня сейчас спросите: "А зачем тебе вложенные друг в друга grid-ы? Почему не обойтись одним?". И ответ: в данном случае можно обойтись. Но существуют ситуации, когда вы вынуждены использовать вложенные контейнеры, например, когда вы внутри виджета. Но давайте упростим код и обойдемся одним grid-ом:

<style>
      html, body {
        height: 100%;
        padding: 0px;
        margin: 0px;
      }
      .root {
        width: 100%;
        height: 100%;
        background-color: yellow;   
        display: grid;
        overflow: hidden;
      }
      .toolbar1, .toolbar2-1 {
        background-color: green;
      }
      .main {
        background-color: grey;
        overflow: auto;
      }
      .main-big-content {
        background-color: black;
        height: 2000px;
      }
      .toolbar2, .toolbar2-2 {
        background-color: cyan;
      }
    </style>
    <div class="root">
      <div class="toolbar1">
        <button>button1</button>
      </div>
      <div class="toolbar2-1">
        <button>button2-1</button>
      </div>
      <div class="main">
        <div class="main-big-content">
        </div>
      </div>
      <div class="toolbar2-2">
        <button>button2-2</button>
      </div>
      <div class="toolbar2">
        <button>button1</button>
      </div>
    </div>

Идеально. Начинайте использовать grid-ы!

Источник: https://habr.com/ru/articles/772834/


Интересные статьи

Интересные статьи

Данный вопрос встал при миграции облачных ресурсов в Яндекс.Облако. Официальная документация, к сожалению, не дает ответа на этот счет, как и гуглёж. Однако, можно применить подход, который использует...
В сообществе тестировщиков много спорят о том, сколько assert-ов должно быть в одном автоматизированном тесте пользовательского интерфейса. Некоторые считают, что на один тест должен прих...
Все началось в 6 утра 12 мая. На связанную с нашими аккаунтами почту пришло «письмо несчастья». Красочно оформленный шаблон сообщал, что приложение для изучения английских слов за...
Недавно я работал над современной реализацией блогролла (перечня внешних полезных/интересных блогов). Замысел был в том, чтобы предоставить читателям подборку из последних постов в этих блогах,...
Каким образом за столетия до изобретения подъёмных кранов и грузовиков были созданы древние сооружения наподобие Стоунхенджа или статуй Моа́и на острове Пасхи? В своём новом эксперименте иссл...