Моя перша практика з CSS Grid Layout

22

Від автора: як і багато моїх колег, я з великим очікуванням спостерігав дивно швидке прийняття CSS Grid Layout, щоб продемонструвати, задокументувати і самому проповідувати цей набір нових інструментів дизайну, які перевернули все з ніг на голову.

Моя перша практика з CSS Grid Layout

На жаль, мій мозок, як правило, прагне позбутися технічних знань, якими я ще не зміг знайти практичного застосування. Як би я не хотів запам’ятати всі правила grid-* після перегляду відео або вивчення демо, зробити це дуже складно. Те ж саме і зі стилями під Firefox Developer Edition і прапором у Chrome.

Проте з виходом Firefox 52 і Chrome 57 ситуація змінилася. І майже відразу ж виникла проблема в одному з наших проектів, який являв собою простий, автономний приклад того, як сітчастий макет може все спростити. Хоча мій приклад не такий вражаючий або надихаючий, як експерименти по макетуванню Jen Simmons, для мене це маленька перемога. І як часто буває, такі маленькі перемоги часто відкривають шлях до чогось більшого.

Завдання

Моя перша практика з CSS Grid Layout

Мені видали контент сторінки з таким пріоритетом:

вступний текст;

працюючі посилання в двох розділах;

текст з детальним роз’ясненням.

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

Структура розмітки:

Старий спосіб

У цьому дизайні нам потрібно, щоб всі елементи відступали один від одного на 1.5 em зі всіх сторін. Спочатку я застосував техніку полупаддингов контейнера і його дочірніх елементів від Samantha Zhang:

.container,
.prose,
.sidebar {
padding: 0.75 em;
}

Але вона не враховує блоки сайдбара, яким теж потрібні відступи. І padding використовувати я не можу, це спотворить зовнішній вигляд. Можна було б додати контейнери, але я вибрав margin) і display: flex;, щоб запобігти схлопування відступів (нам у будь-якому випадку знадобиться Flexbox на цих елементах). Також потрібно прибрати деякі магдіп’и сайдбара, щоб врахувати подвійний відступ:

.sidebar {
display: flex;
flex-direction: column;
margin: -0.75 em;
position: relative;
}
.box {
margin: 0.75 em;
}

Пора додати адаптивності! На середніх вьюпортах можна повернутися до правилом display: flex, з допомогою якого ми розподілили контент сайдбара рівномірно по рядку:

@media (min-width: 34em) and (max-width: 49.9375 em) {
.sidebar {
flex-direction: row;
}
.box {
flex: 50%;
}
}

На широких вьюпортах я хочу, щоб сайдбар з’їжджав вправо, а контент був ліворуч. Я вирішив додати обтікання обом елементів, а це значить, що мені знадобиться clearfix на контейнері:

.container::after {
clear: both;
content: «»;
display: table;
}
@media (min-width: 50em) {
.prose {
float: left;
width: 66.666%;
}
.sidebar {
float: right;
width: 33.333%;
}
}

Результат з підкресленими елементами макета:

Моя перша практика з CSS Grid Layout

Так в чому проблема?

Незважаючи на те, що CSS в цьому демо не самий геніальний, деякі самі незрозумілі прийоми легко прийняти як належне:

щоб отримати рівні відступи навколо адаптивних шаблонів, необхідно половину відступу застосувати до контейнера і половину до його дочірніх елементів;

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

так як ми додали обтікання до всіх дочірніх елементів, ми змушені були використовувати псевдоелементи для штучної очищення контейнера, щоб уникнути порушення в компонуванні елементів сторінки.

Ви могли б сказати: «а чому ти не скористався іншою технікою?». Однак технік без компромісів дуже мало. Якщо сайдбар позиціонувати абсолютно, то його вміст не зможе перевищувати основний контент. Якщо перемістити сайдбар в кінець розмітки і змінювати його властивості order на маленьких розмірах, то вам доведеться налаштовувати індекси вкладок для допоміжних устройсв.

CSS Grid Layout в цьому плані відрізняється. Він був побудований з нуля під дві осі одночасно. Давайте подивимося, як Grid Layout застосовується до цього макету.

Спосіб з Grid

Я кажу браузеру, що контейнер буде використовувати сітку, а відступи між елементами повинні бути 1.5 em… без роздільників:

.container {
display: grid;
grid-gap: 1.5 em;
padding: 1.5 em;
}

В сайдбарі будуть ті ж стилі макета і відступи. Насправді, можна було б використовувати display: subgrid, але поки що це занадто складно:

.sidebar {
display: inherit;
grid-gap: inherit;
}

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

@media (min-width: 34em) and (max-width: 49.9375 em) {
.sidebar {
grid-template-columns: 1fr 1fr;
}
}

(З’явилися нові одиниці вимірювання fr, і я обожнюю їх. Скорочення розшифровується як «fractional» і означає «одна частина доступного простору». Можна було б використовувати 50% 50%, але тоді треба було б обчислювати grid-gap.)

На великих розмірах ми застосовуємо цю ж техніку до контейнера, тільки першу колонку ми робимо 2fr, щоб вона займала дві третини вільного простору:

@media (min-width: 50em) {
.container {
grid-template-columns: 2fr 1fr;
}
}

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

@media (min-width: 50em) {
.sidebar {
grid-auto-rows: min-content;
grid-row: span 2;
}
}

От і все! Свіжа версія з grid нашого раннього демо в тому варіанті, як вона з’явиться в останніх версіях Firefox і Chrome:

Моя перша практика з CSS Grid Layout

Майже на половину менше CSS, немає негативних магдіп’ов, і майже немає обчислень! Ура!

Забуваємо, що вчили

Час сповіді: мені важко далося демо вище. Мені довелося часто просити допомоги у мого колеги Erik Jung з Cloud Four, щоб все запрацювало так, як замислювалося. Озираючись назад, мені здається, що моїм найголовнішим ворогом був мій власний 15-річний досвід написання стилів. Я настільки звик до того, що має абстрагуватися від задачі дизайну, звик до того, що я повинен говорити мовою CSS і працювати над його примхами, що зробив завдання складніше, ніж це було потрібно. Я витрачали час, намагаючись хакнуть якісь проблеми, коли все, що потрібно було зробити, це сказати «гей, розтягни div на два ряди».

З цієї вправи я виніс для себе, що CSS Grid Layout це дивовижний інструмент, і я ледь зрозумів межі його можливостей. Також приємно, що браузери з підтримкою Grid підтримують функціональні запити, і, можливо, ми зможемо ними користуватися набагато раніше, ніж думали. Наступного разу, коли я буду боротися з макетом, спробую підійти до проблеми, як учень, опираючись ментальним «мозолів», що сформувалися за роки обхідних рішень.