На данный момент, по данным Can I Use, 84% браузеров поддерживает Grid Layout. С каждым месяцем это число растет. А ведь буквально недавно этот модуль находился за флагом. Поэтому если Вы еще не знакомы с теми возможностями, которые он предоставляет, то самое время это исправить.
В качестве примера я выбрал галерею изображений с сайта Кинопоиск, которая создана с помощью относительного позиционирования. При реализации мы будем руководствоваться принципом «воруй, но улучшай», поэтому наша галерея будет гибкая и адаптирована под различные разрешения.
Первым шагом является создание контейнера под фотографии. Каждому элементу будет присвоено два класса: общий, для всех фотографий, и уникальный (надеюсь, что вы не используете идентификаторы, так?).
<div class="container">
<div class="photo photo1"></div>
<!-- Остальные элементы -->
<div class="photo photo20"></div>
</div>
Наш родительский элемент попросим вести себя как
Распределение элементов в грид-контейнере
Затем создадим несимметричную сетку из имеющихся элементов. Мы будет это делать, указывая начальную и конечную координату треков (полосы между клетками).
.photo1 {
/* от какой строки */
grid-row-start: 1;
/* до какой строки */
grid-row-end: 3;
/* от какого столбца */
grid-column-start: 1;
/* до какого столбца */
grid-column-end: 3;
}
Выглядит громоздко. Вам не кажется?
.photo1 {
grid-row: 1 / 3;
grid-column: 1 / 3;
}
Уже лучше, но можно еще короче.
.photo1 {
grid-area: 1 / 1 / span 2 / span 2;
}
Вы разумеется заметили, что мы еще заменили тройки на span 2. Это сделано для того, чтобы не считать треки. Мы просто говорим браузеру — через какое количество клеток элемент будет протянут. А теперь нам нужно сделать это для каждого блока. Кстати, если не указывать конечную позицию, то элемент будет занимать ровно одну клетку.
После этого добавим элементам фоновое изображение, которое будет масштабироваться с сохранением пропорций.
.photo {
background-size: cover;
}
.photo1 {
background-image: url(...);
}
Наглядная нумерация треков. Ах да, вы можете считать их с конца, только перед значением нужно не забыть указать минус.
Такую же операцию мы проведем для следующего брейкпоинта, где наша галерея будет иметь размеры 10 на 5. Все, что мы сделали это — поменяли значение свойства grid-area у элементов и добавили одно изображение из-за то, что при переопределении сетки у нас образовалась пустая область. К сожалению, при создании media-выражения нельзя воспользоваться функцией calc (на момент написания статьи эта возможность реализована только в Chrome 66, Firefox 59 и Opera 53), поэтому расчеты приведены в комментариях к коду. Считается это так: сумма ширины элемента и его отступа умноженное на количество колонок в предыдущем брейкпоинте.
/* (75px + 5px) * 13 columns = 1040px */
@media (max-width: 1040px) {
.container {
grid: repeat(5, 75px) / repeat(10, 75px);
}
/* Здесь будет новое определение позиций для остальных элементов */
.photo20 {
grid-area: 4 / 9 / span 2 / span 2;
}
}
На самом последнем брейкпоинте все наши изображения будут одного размера, а, значит будут занимать ровно одну клетку. Для реализации такого поведения мы переопределим количество элементов в контейнере на 20 и установим классу photo (данный класс имеется у каждого изображения) свойство grid-area на значение по умолчанию — auto. Тем самым, мы сбросили параметры, заданные в предыдущем брейкпоинте. Теперь наши блоки автоматически распределяются по клеткам слева направо.
/* (75px + 5px) * 10 columns = 800px */
@media (max-width: 800px) {
.container {
grid: repeat(4, 75px) / repeat(5, 75px);
}
.photo {
grid-area: auto / auto;
}
}
Заключение
Как видите, новый модуль CSS довольно гибок и прост в обучении. Разумеется, я не воспользовался в этой статье всеми возможностями, которые он предоставляет. Но уже на данном примере наглядно продемонстрирована мощь этого инструмента. Надеюсь, что для Вас это станет отрывной точкой в изучении Grid Layout, и Вы будете готовы к его использованию, как только ваш блог/сайт сможет себе позволить прекратить поддержку старых браузеров.
UPD: Благодаря пользователю Loki3000 было найдено решение, которое является более элегантным. О его выгодах Вы можете прочитать в комментариях к данной публикации.