Знайомство з CSS Grid Layout


CSS Grid - найважливіша подія для побудови веб-макетів, з часів гумових контейнерів (флексбоксів). Вона дозволяє уникнути використання будь-яких магічних методів, хитростей та обхідних шляхів, до яких ми звикли за останні 15 років. З сіткою стало набагато простіше описувати макети, впевнений, сітка знищить більшість провідних CSS-фреймворків і дозволить писати менше стилів.

Якщо ви не знайомі з CSS Grid Layout і дочитали аж до цього місця, знайте, це інструмент для розробки макетів, який дозволяє керувати розміщенням, розмірами і вирівнюванням дочірніх елементів.

CSS-сітка надає нові потужні можливості та дозволяє розташуванню елементів одночасно враховувати горизонтальний і вертикальний вільний простір без використання медіазапитів, сітка дозволяє дуже легко змінювати розташування елементів, без зміни структури документа.

Вивчення необхідного мінімуму

Спочатку може здатися, що для розуміння сітки, треба вивчити багато нового синтаксису, але вам потрібно розуміти лише частину, щоб почати. У цій статті буде використано приклади, щоб ознайомити вас з різними концепціями, важливими для початку створення CSS Grid.

Браузерна сумісність

Підтримка CSS Grid з'явилася в Safari 10.1, Firefox 52, Opera 44, Chrome 57. MS Edge працює над оновленням Grid для Edge 15.

Існує застаріла реалізація, доступна браузерам Microsoft (IE10-11 та Edge 13-14), які мають ряд обмежень, ми коротко розглянемо застарілу реалізацію, щоб пояснити деякі відмінності між новітніми та старшими реалізаціями та способами обійти їх.

Для більшості макетів ми будемо використовувати наступну перевірку можливостей, щоб старі браузери як і раніше підтримували саме те розташування, яке вони розуміють:

@supports (display: grid) {
    .grid {
        display: grid;
    }
}

Браузери, які не підтримують @supports або не підтримують сітку, не будуть використовувати цю функцію.

Щоб правильно слідкувати за наведеними в цій статті прикладами, вам потрібно буде використовувати веб-переглядач із підтримкою Grid.

Створення сітки з двома стовпчиками та жолобом між ними

Щоб продемонструвати, як CSS Grid визначає стовпчики, ми почнемо з цього макета:

Два стовпчики з жолобами з використанням grid-template-columns і grid-gapДва стовпчики з жолобами з використанням grid-template-columns і grid-gap

Щоб створити цю сітку, ми повинні використовувати grid-template-columns та grid-gap

grid-template-columns визначає, як будуть розташовуватися стовпчики сітки, вона приймає ряд значень, розділених пропусками, які задають розмір кожного стовпчика, а кількість вказаних значень дає нам кількість стовпчиків.

Наприклад, чотири стовпчики, з шининою у 250 пікселів можуть бути визначені таким чином:

grid-template-columns: 250px 250px 250px 250px;

Той же макет може також бути виражений з використанням ключового слова repeat (повторити).

grid-template-columns: repeat(4, 250px);

Визначення жолобків (проміжків між стовпчиками)

grid-gap задає розмір жолобів у макеті сітки, він може приймати одне чи два значення, якщо ви вказали два значення, то вони застосовуються для рядків і стовпчиків у відповідному порядку.

У нашому макеті розділеному на два стовпчикі ми можемо оголосити нашу сітку таким чином:

.grid {
  display: grid;
  grid-template-columns: 50vw 50vw;
  grid-gap: 1rem;
}

На жаль, розрив буде додано до загальної ширини контейнера, яка буде розраховуватися так: 100vw + 1rem, і макет матиме горизонтальну смужку прокручування.

Горизонтальна смужка прокрутки використовує ширину жолобка разом з блоками переглядуГоризонтальна смужка прокрутки використовує ширину жолобка разом з блоками перегляду

Для виправлення цього переповнення потрібно трохи інше рішення. Вводимо одиницю частки (від англ. Fraction) - FR.

Одиниця частки

fr займає частку вільного простору; якщо 900px був доступним простором, а елемент мав одну частку ширини, а інший мав дві частки - перший отримав би 1/3 простору, а другий отримав би 2/3 простору від цих спільних 900 пікселів.

Змінюємо наш код, замінюючи одиниці в'юпорту на частки:

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap: 1rem;
}

Вирівнювання вмісту

Щоб вирівняти вміст у нашому прикладі, ми оголошуємо, що дочірні елементи будуть повидитися як сітка та використовуємо властивості вирівнювання, щоб розмістити їх на відповідних треках; трек - це лише загальна назва для чогось стовпця чи рядка (є і сіткові треки, які їх оточують). Сітка, як і Flexbox, має ряд властивостей вирівнювання та чотири значення - start (початок), center (центр), end (кінець) і stretch (розтягнути), і які вказують, де дочірні елементи мусять знаходяться на відведеному для них треку. stretch, на відміну від інших, розтягне елемент від початку і до кінця свого треку.

align-items і justify-contentalign-items і justify-content

У нашому прикладі, щоб вирівняти вміст у центрі, як по вертикалі, так і по горизонталі, ми можемо застосувати ці властивості до контейнера:

.center-content {
    display: grid;
    align-items: center;
    justify-content: center;
}

Приклад двух стовпців

Відтворення макета з двома стовпчиками з допомогою старої версії CSS Grid

Щоб відтворити макет з допомогою старої сітки, ми повинні пам'ятати про ряд обмежень. У старій реалізації не тільки немає grid-gap, так ви ще й повинні оголосити для кожного елементу сітки, де він починається, інакше за замовчуванням він буде 1, що змусить усі дочірні елементи складатися один під одного в першій колонці.

У макеті, що нижче має враховуватися відсутність окремої властивості для інтервалів, також, потрібно вказати кожному елементу, де він починається:

.grid-legacy {
   display: -ms-grid;
   -ms-grid-columns: 1fr 1rem 1fr; // gap replacement
}
.grid-legacy:first-child {
   -ms-grid-column: 1;
}
.grid-legacy:last-child {
    -ms-grid-column: 3;
}

Вирівнювання та розтягування старої сітки

Стара сітка має подібну проблему як і Flexbox в IE11, якщо встановити мінімальну висоту для контейнера, вона не обов'язково буде застосовуватися. Але цю проблему набагато простіше виправити з Grid.

Для цього ми можемо використовувати функцію minmax для рядка батьківського контейнера. minmax визначає діапазон найбільших і найменших значень, які можуть бути у рядка чи стовпчика.

-ms-grid-rows: minmax(100vh, 1fr);

Дочірні елементи ми можемо зробити сіткою і встановити єдину колонку шириною у 1fr.

.ms-cell {
   -ms-grid-columns: 1fr;
   -ms-grid-rows: 1fr;
}

Також, ми не можемо вирівнювати сітку за допомогою батьківсьх елементів, як у Flexbox, або сучасної Grid. Тому, ми маємо використовувати самі елементи для вирівнювання.

.ms-align-center {
    -ms-grid-column: 1;
    -ms-grid-column-align: center; // like align-self in modern grid
    -ms-grid-row-align: center; // like justify-self in modern grid
}

Макет двух стовпчиків зі старою сіткою

На сьогоднішні ми розглянули, як створити стовпчики, жолобки, вирівняти вміст і як підтримувати роботу сітки в більшості браузерів. Давайте спробуємо створити від'ємний простір за допомогою сітки.

Створення від'ємного простору за допомогою CSS Grid

Одна можливість, яку Grid дозволяє вам зробити, це оголосити, де починаються стовпчики у сітці за допомогою властивості grid-column-start, це дає нам можливість для створення від'ємного простору в сітці.

Від'ємний простір за допомогою grid-template-columns і grid-column-startВід'ємний простір за допомогою grid-template-columns і grid-column-start

Одним із способів створення від'ємного простору є встановлення стовпчика з номером, що перевищує його фактичну позицію, залишаючи призначене для нього місце у сітці пустим, таким чином наш стовпчик буде зсунутий по горизонталі.

Зміщення першого елемента разом із grid-column-startЗміщення першого елемента разом із grid-column-start

У наведеному вище прикладі створення негативного простору, розмітка є div-ом, який в свою чергу є упаковкою для іншого div-a.

<div class="grid">
    <div class="child"><!-- content --></div>
</div>

Сітку визначено так:

.grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
}

Щоб змусити дочірній елемент починатися з правого стопцика, ми говоримо йому починатися зі стовпчика номер 2.

.child {
    grid-column-start: 2;
}

Примітка: невідповідність у Firefox 52 викликає проблеми з вертикальним вирівнюванням, коли одиниця fr для висоти рядка не розтягується до повної висоти вікна браузера, для вирішення цієї проблеми ми робимо дочірні елменти сітковими (grid-елементами) та додаємо один єдиний рядок нам бажаної висоти.

.l-grid--full-height {
    grid-template-rows: minmax(100vh, 1fr);
}

Приклад створення негативного простору

Створення "мертвих зон" у вмісті

Створення мертвої зони використовуючи grid-template-columns і grid-column-startСтворення мертвої зони використовуючи grid-template-columns і grid-column-start

Трек сітки буде пропускати стовпці, доки не знайде вільний. Це дає нам метод створення вільного простору всередині сітки, де не буде розташовано жодної доріжоки з контентом.

Приклад такої "мертвої зони"

Створення рядків

Що робити, якщо ми хочемо розбити макет на чотири частини? Все, що ми розглянули до цих пір, стосовно стовпчиків також стосується і рядків.

.grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 250px 250px;
}

Створення макету сітки використовуючи grid-template-columns і grid-template-rows разомСтворення макету сітки використовуючи grid-template-columns і grid-template-rows разом

Проблема в цьому прикладі - це ідеальний сценарій. Вміст кожного елемента сітки досить малий, щоб ніколи не порушувати зазначений розмір рядка. Коли справа стосується рядків, контент змінює все. Ось вам приклад того, що трапляється, коли ваш контент переповнить вказаний розмір рядочка:

Зміст переповнив заявлені розміри рядочківЗміст переповнив заявлені розміри рядочків

Ми створили два рядочки, висота кожного 250 пікселів. Якщо вміст всередині рядка переповнює його, він вилазить з ряду та починає перекривати під ним вміст. Це не зовсім бажаний результатЮ, вірно?

Встановлення мінімальних розмірів зі зберіганням гнучкості

У цьому прикладі нам потрібно встановити мінімальний розмір, але дозволити йому бути гнучким для змісту. Ми можемо досягти цього, використовуючи ключове слово minmax, яке ми вже використовували раніше.

.grid {
    grid-template-rows: minmax(250px, auto) minmax(250px, auto);
}

Тепер, коли ми розглянули основи, необхідні для створення рядків із вмістом, ми можемо почати створювати більш складні сітки: горизонтальні та вертикальні.

Створення гнучких рядjxків з мінімальними розмірами

Використання grid-column-start і ключового слова span для створення повноцінною сітки. Фото з UnsplashВикористання grid-column-start і ключового слова span для створення повноцінною сітки. Фото з Unsplash

Створення більш складних сіток

Давайте почнемо створювати більш складні сітки, розміщуючи елементи на кількох доріжках одночасно всередині сітки. У стовпчиках ми можемо це досягти за допомогою grid-column-start і grid-column-end, або записати це більш скорочено, таким чином:

grid-column: 1 / 3;

Недоліком цього підходу є те, що він не дуже модульний, тому, це може призвести до написання об'ємного коду для позиціонування частин вмісту.

Ключове слово span є більш модульним, оскільки ми можемо розмістити його в будь-якому місці та дозволити сітці вирахувати все самій. Це дозволяє нам розтягнути елемент на декілька доріжок починаючи з його початкової позиції:

.span-column-3 {
    grid-column-start: span 3;
}

До якого б елементу ми не присвоїли цей клас, це змусить його розтягнутися на три доріжки з його поточної позиції.

Створення складних сіток за допомогою span

Планування макета з використанням span

Ми можемо планувати багатосмугові макети, б'ючи розташування кожної комірки до найменшої одиниці в макеті сітки. У цьому прикладі виділена найменша одиниця:

Найменший елемент grid використовується для стовпчиків сітки, тому ми можемо створювати більші елементи зі spanНайменший елемент grid використовується для стовпчиків сітки, тому ми можемо створювати більші елементи зі span

Розбудовуючи все навколо найменшої одиниці, ми можемо гнучко застосовувати класи зі span, щоб створювати цікаві макети, і оскільки значення span додаються - ви можете поєднувати треки як по рядочках так і стовпчиках для створення ієрархії в своїй сітці.

Адаптивні сітки без використання медіа запитів

Незважаючи на те, що деякі з попередніх прикладів можуть пристосовуватися до змін простору, ніхто з них не був спеціально написаний для цих цілей. Сітка має дві надзвичайно потужні функції для управління вільним простором. Ці функції називаються auto-fit та auto-fill і використовуються в рамках функції repeat зазвичай з функцією minmax, наприклад:

grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

Вони замінюють собою числа в функції і обчислюють максимально можливу кількість рядочків та стовпчив у сітці. Основними відмінностями між ними є те, як вони вирішують наявність вільного простору на лінії.

auto-fill спробує розмістити найбільшу можливу кількість повторюваних елементів у стовпчик, яким він може керувати без переповнення. Коли місця для додавання іншого елемента недостатньо, наступний елемент буде розміщений на наступному рядку, а простір, який він не зміг заповнити, залишається вільним.

Автозаповнення може залишити пустий простір позаду, тому що auto-fit згорне порожні простори до 0 пікселівАвтозаповнення може залишити пустий простір позаду, тому що auto-fit згорне порожні простори до 0 пікселів

auto-fit поводиться аналогічним чином для автозаповнення, за винятком того, що будь-який порожній простір згортатиметься, а елементи розтягуватимуться в цьому рядку, що нагадує поведінку Flexbox, який згортає стовпчики, коли доступний простір зменшується.

Приклад використання grid-auto-fitПриклад використання grid-auto-fit

Макет, який спирається на медіа запити, прив'язаний до області перегляду, і це не підходить для модульних елементів - компоненти всередині сітки мають мати можливість адаптуватися до наявного простору. Отже, як це може виглядати на практиці?

grid auto-fit на практиціgrid auto-fit на практиці

Приклад використання grid auto-fit

Це лише початок

Ми мали майже п'ятнадцять років домінування float в макетах CSS, ми дізналися про все, що можна зробити з ним, а CSS Grid - це ще тільки новачок, з яким треба ще багато експериментувати та навчатися.

На даний момент найважливішим кроком є початок використання сітки, створюючи більш просунуті макети. Сітка - це майже невідома територія, і як тільки ми краще зрозуміємо всі її можливості та починемо поєднувати її з іншими технологіями, ми зможемо робити цікавіші, гнучкіші макети без зайвих стилів й зможемо забути про окремі фреймворки.

Якщо у вас з'явилося бажання продовжити знайомство з CSS Grid після цієї статті, спробуйте погратися з GridByExample від Рейчела Ендрю, де показується кожний аспект сіток на прикладах з поясненнями.


Переклад статті "Getting to know CSS Grid Layout" Кріса Райта


  css,grid,сітка     29-11-2017