Masonry-раскладка на CSS: Прощайте, костыли и тяжелые библиотеки
Слушай, помнишь тот момент, когда дизайнер приносит макет в стиле Pinterest? Ты смотришь на эти карточки разной высоты, которые идеально подтягиваются друг к другу без пустых дырок, и в голове сразу начинает играть похоронный марш. Почему? Потому что до недавнего времени сделать честный Masonry на чистом CSS было той еще задачкой со звездочкой.
Мы привыкли к сеткам, где всё выровнено по линеечке. Но в реальной жизни контент — это хаос. Тексты бывают разной длины, а картинки — разных пропорций. Нам нужно решение, которое само разрулит пустоты, не превращая код в месиво из JavaScript-расчетов. И, спойлер: в 2026 году мы наконец-то получили то, чего ждали десятилетие.
Как мы страдали раньше
Вспомни эти темные времена. Вариантов было три, и все они — так себе. Первый — старый добрый Masonry.js или Isotope. Подключаешь жирную библиотеку, которая на каждый ресайз окна пересчитывает абсолютные координаты каждого элемента. Минус производительность, плюс головная боль с инициализацией.
Второй вариант — column-count. Вроде бы просто, но есть нюанс: элементы в колонках идут сверху вниз. Если у тебя список новостей, то первая новость будет сверху в первой колонке, а вторая — где-то в середине макета в той же колонке. Пользователь ломает глаза, пытаясь понять порядок чтения. Чтобы контент выглядел адекватно, часто приходилось вспоминать базу, например, 10 актуальных способов отцентровать div, но для раскладки а-ля Pinterest этого явно не хватало.
Третий — «костыльный» Grid с grid-row: span. Нам приходилось на бэкенде или через JS вычислять высоту контента и динамически пробрасывать количество занимаемых ячеек в инлайновые стили. Это работало, но ощущалось как попытка забить гвоздь микроскопом.
Как делать правильно в 2026 году
Современный стандарт CSS Grid (Level 3) представил свойство, которое меняет правила игры: grid-template-rows: masonry. Больше никаких расчетов! Мы просто говорим контейнеру: «Эй, будь гридом, но по строкам веди себя как Masonry».
Браузер сам берет элементы и «подтягивает» их в ближайшее свободное пространство по вертикали, сохраняя при этом логичный порядок в коде (справа налево, сверху вниз). Это идеальное комбо для производительности и доступности. Кстати, если ты пихаешь в такую сетку картинки, не забудь про идеальные изображения со свойствами object-fit и object-position, чтобы они не разъезжались и сохраняли свои пропорции внутри карточек.
Готовый сниппет кода
Лови максимально лаконичный пример. Весь фокус — в одной строчке CSS. Обрати внимание, как просто теперь описывается сложная логика подтягивания блоков.
/* Родительский контейнер */
.masonry-grid {
display: grid;
/* Указываем количество колонок */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
/* Включаем магию Masonry для строк */
grid-template-rows: masonry;
/* Расстояние между карточками */
gap: 20px;
padding: 20px;
}
/* Стили для самих карточек */
.card {
background: #f4f4f4;
border-radius: 12px;
padding: 15px;
border: 1px solid #ddd;
}
/* Просто для наглядности: карточки разной высоты */
.card:nth-child(odd) {
min-height: 150px;
}
.card:nth-child(even) {
min-height: 250px;
}
Частая ошибка новичков
Самый популярный капкан — попытка использовать align-items: stretch или задавать жесткую высоту (height: 100%) элементам внутри Masonry-сетки. Если ты заставишь все карточки тянуться до высоты самой длинной в ряду, весь эффект Masonry моментально испарится, и ты получишь обычный скучный Grid.
Вторая ошибка — забывать про прогрессивное улучшение. Пока нативная поддержка grid-template-rows: masonry еще докатывается до старых версий некоторых браузеров, всегда стоит иметь запасной план в виде обычного display: block или колонок, чтобы контент оставался читаемым, даже если «магия» не сработала.
🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!