Как вписать блоки в страницу или в контейнер? Используйте 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/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *