Колонки з автоматичним підбором розмірів в CSS Grid: auto-fill або auto-fit

444

Від автора: крім явно заданих розмірів колонок в CSS Grid є ще одна з потужних і зручних функцій – це можливість автоматично повторювати CSS колонки і робити автоподстановку елементів в них. Якщо точніше, то ми можемо вказати кількість колонок у сітці, а браузер буде їх адаптивно підлаштовувати під нас: на маленьких вьюпортах колонок буде менше, на великих – більше. І не потрібно писати медіа запити і строго прописувати адаптивне поведінку.

Все це доступно лише одному рядку CSS – мені це нагадує, як Дамблдор махнув своєю паличкою будинку у Горація і «меблі повернулася на свої місця, прикраси взмахнули в повітря, подушки набилися пір’ям, подерті книги самі себе відреставрували і приземлилися на полиці…».

Таке магічне поведінку без підключення адаптивності досягається через функцію repeat() і ключові слова автопідстановки.

Про цьому рядку вже написано багато статей, тому я не буду зупинятися на тому, як це працює. Tim Wright написав чудову статтю, рекомендую до прочтенью.

Загалом, функція repeat() дозволяє повторювати колонки скільки завгодно разів. Наприклад, якщо вам потрібна 12-ти колоночная сітка, можна написати так:

.grid {
display: grid;
/* define the number of grid columns */
grid-template-columns: repeat(12, 1fr);
}

1fr – ця запис говорить браузеру розтягнути простір між колонок рівномірно. Тобто ми отримуємо рідкі і рівні по ширині колонки. В такому випадку сітка завжди буде розтягуватися на 12 колонок, незважаючи на ширину. Як ви здогадалися, це недобре. На маленьких екранах контент може сильно стиснутися.

Тому необхідно задати мінімальну ширину колонок, щоб вони не стали дуже вузькими. Для цього нам знадобиться функція minmax().

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

Але тоді в CSS Grid переповниться рядок. Колонки не переїдуть на нові рядки, якщо ширина вьюпорта недостатня, щоб вмістити всі колонки з новою мінімальною шириною. Ми ж сказали браузеру повторювати колонки 12 разів у рядку.

Щоб колонки переносилися можна використовувати auto-fit або auto-fill.

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

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

З auto-fit ви можете отримає в кінці рядка порожній простір. Але коли і як? Давайте дізнаємося.

Fill або fit? В чому різниця?

На недавньому семінарі з CSS я говорив про різницю auto-fill і auto-fit:

«auto-fill ЗАПОВНЮЄ рядок максимально можливою кількістю колонок. Якщо в рядок можна вмістити нову колонку, вона буде створена з чітко заданою шириною, тому що це ключове слово намагається ЗАПОВНИТИ рядок максимальною кількістю колонок. Нові колонки можуть бути порожніми, але вони все ж будуть займати місце в рядку.

auto-fit ПІДЛАШТОВУЄ доступні на даний момент колонки під простір, розширюючи їх, щоб вони могли зайняти увесь доступний простір. Браузер спочатку заповнює вільний простір додатковими колонками (як auto-fill), після чого порожні колонки стискаються.»

Спочатку може здатися дивним, але якщо розібрати наочний приклад, все стане зрозуміло. Це ми і зробимо з допомогою Firefox DevTools Grid Inspector. Цей інструмент допоможе нам візуалізувати розмір і положення елементів, сітки і колонок.

Розберемо демо нижче.

Колонки задано через функцію repeat() і мають мінімальну ширину 100px, максимальна ширина 1fr. Колонки будуть рівномірно розширюватися на будь-який вільний простір. Для колонок у рядку ми будемо використовувати ключові слова автопідстановки, і браузер сам подбати про адаптивності сітки і перенесення колонок на нові рядки при необхідності.

Браузер розмістить колонки і задасть їм розмір в першому прикладі з допомогою auto-fill, після чого буде застосований auto-fit.

.grid-container–fill {
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}
.grid-container–fit {
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

До певного моменту auto-fill і auto-fit ведуть себе однаково.

Колонки з автоматичним підбором розмірів в CSS Grid: auto-fill або auto-fit

Але всередині вони працюють по-різному. Вони дають один результат на певній ширині вьюпорта.

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

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

Коли рядок може вмістити нову колонку, браузер веде себе:

«у мене з’явилося місце на ще одну колонку. У мене є контент, який може перейти в цю колонку? Так? ОК, добре. Я додам у рядок нову колонку, а на маленьких вьюпортах вона буде перестрибувати на новий рядок.»

коли немає контенту для нової колонки: «чи Можу я дозволити новій колонці зайняти місце в рядку (тим самим вплинути на положення і розмір інших рядків)? Або я можу схлопнуть цю колонку і використовувати її простір для розширення існуючих?»

auto-fill і auto-fit зают відповідь на останнє питання, а також визначають поведінку браузера в цьому сценарії. Стискати або не стискати, ось в чому питання. І це відповідь.

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

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

Бачите? Якщо поки що не зрозуміли, відео нижче повинна пояснити:

auto-fill: максимально заповнює рядок! Додає максимально можливе число колонок. Неважливо що вони порожні – вони повинні бути. Якщо є місце під нову колонку, додай її. Неважливо, порожня вона чи ні, вона займає місце в рядки, як ніби вона повністю забита (заповнена контентом/grid елементами).

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

auto-fit теж заповнює рядок новими колонками при збільшенні ширини вьюпорта, але нові колонки стиснуті (і їх роздільники). Це можна подивитися в Grid inspector. Подивіться на кількість рядків у сітці, їх стає більше при збільшенні ширини.

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

Важливо пам’ятати, що колонки додаються в обох випадках (стиснуті вони чи ні), і їхні розміри явно не вказані, – це особливо підкреслено в специфікації. У нашому випадку ми додаємо/створюємо колонки в сітку з точними розмірами точно так само, як в сітку з 12 колонок, наприклад. Тому номер -1 означає кінець сітки, що не підходить, якщо колонки створюються без розмірів. Спасибі Rachel Andrew за цю пораду.

Висновок

Різниця між auto-fill і auto-fit стає помітна тільки, коли рядок може містити додаткові колонки.

Якщо ви використовуєте auto-fit, контент буде розтягуватися, щоб заповнити ширину рядка. А з auto-fill браузер дозволяє порожнім колонкам займати простір у рядку, як ніби вони не порожні – вони будуть займати простір, навіть якщо у них немає елементів, сітки, тобто вони будуть впливати на розмір/ширину колонок.

Яка поведінка вибрати-вирішуйте самі. Мені досі здається, що auto-fill не краще ніж auto-fit. А як ви їх використали? Якщо використовували, пишіть про це в коментарях.