CSS Subgrid: почему мы ждали этого так долго и как это использовать
Присаживайся, бери кофе. Сегодня поговорим о вещи, которая годами заставляла фронтендеров тихо плакать в подушку по ночам, а потом изобретать безумные костыли на JavaScript. Да, я говорю о выравнивании независимых элементов в разных колонках сетки. Представь классическую задачу: у тебя есть три карточки в ряд. В каждой карточке — заголовок, описание и кнопка внизу.
Дизайнер хочет, чтобы заголовки были идеально выровнены по одной линии, описания начинались на одном уровне, а кнопки послушно «прилипали» к самому низу, независимо от того, сколько текста налил копирайтер в соседнюю карточку. Казалось бы, базовая задача. Но сколько седых волос она нам принесла!
К счастью, на дворе 2026 год, поддержка CSS Subgrid в браузерах стала абсолютной, и теперь мы можем решать эту проблему элегантно и без боли.
Как мы страдали раньше
Давай вспомним эти «славные» времена. Как мы пытались решить задачу выравнивания контента внутри карточек до появления Subgrid?
- Костыль №1: Фиксированная высота (
min-height). Мы просто замеряли самый длинный заголовок, округляли и писали что-то вродеmin-height: 80pxдля заголовка. Стоило менеджеру добавить на прод заголовок на одну строчку длиннее — и вся верстка плыла. А на мобилках эти фиксированные высоты превращались в уродливые пустые пространства. - Костыль №2: Flexbox с
margin-top: auto. Отличный способ прижать кнопку к низу карточки. Но он совершенно не помогал выровнять заголовки или текст описания между соседними карточками. Если у одной карточки заголовок занимал три строки, а у другой — одну, то текст описания у них начинался на разной высоте. Выглядело это неаккуратно. - Костыль №3: JavaScript-костыли. Наш «любимый» скрипт, который после загрузки страницы пробегался по всем элементам, находил максимальную высоту заголовка и принудительно вешал ее на остальные. Привет, Layout Shifts, мерцание интерфейса при загрузке и проблемы с производительностью на слабых устройствах. Особенно больно это было, когда мы собирали сложные журнальные сетки, где важна идеальная точность.
Как делать правильно в 2026 году
Спасение пришло откуда не ждали — прямо из спецификации CSS Grid. Встречай CSS Subgrid. Это не какая-то отдельная технология, это естественное расширение обычных гридов.
Идея феноменально проста: до появления Subgrid дочерние элементы грид-контейнера могли выстраиваться по сетке, но их собственные дети (внуки родительского контейнера) уже никак не были связаны с основной сеткой. Они жили своей изолированной жизнью.
Свойство grid-template-rows: subgrid (или аналогичное для колонок) говорит дочернему элементу: «Эй, не создавай свою собственную независимую сетку. Вместо этого возьми линии сетки твоего родителя и привяжи свои внутренние элементы прямо к ним».
Теперь карточка не просто занимает место в сетке, она делится своими внутренними рядами с соседними карточками. Если заголовок во второй карточке растягивает первый ряд родительской сетки, заголовки в первой и третьей карточках автоматически подстроятся под эту высоту. Магия!
Кстати, когда начнешь внедрять это в свои проекты, советую сразу разобраться, как дебажить CSS Grid и Flexbox в DevTools. Визуализация линий сабгрида в современных браузерах экономит кучу времени.
Готовый сниппет кода
Хватит теории, давай посмотрим на рабочий код. Вот самый чистый и лаконичный способ сверстать идеально выровненные карточки:
<!-- HTML структура -->
<div class="grid-container">
<div class="card">
<h3>Короткий заголовок</h3>
<p>Простой текст описания.</p>
<button>Купить</button>
</div>
<div class="card">
<h3>Очень длинный заголовок, который переносится на две строки</h3>
<p>А здесь у нас очень много интересного текста, который должен занять больше места.</p>
<button>Подробнее</button>
</div>
<div class="card">
<h3>Еще заголовок</h3>
<p>Средний текст.</p>
<button>Купить</button>
</div>
</div>
<style>
/* Стили сетки */
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
/* Самое важное: каждая карточка будет занимать ровно 3 ряда родительской сетки */
grid-template-rows: auto 1fr auto;
gap: 24px;
}
.card {
display: grid;
/* Говорим карточке занять ровно три ряда в родительском гриде */
grid-row: span 3;
/* А теперь магия: наследуем структуру рядов у родителя */
grid-template-rows: subgrid;
background: #f4f4f9;
padding: 20px;
border-radius: 8px;
}
/* Элементы внутри карточки автоматически попадают в ряды сабгрида */
.card h3 {
margin: 0;
}
.card p {
margin: 0;
}
.card button {
align-self: end;
}
</style>
Частая ошибка новичков
Самый частый затык у тех, кто только начинает щупать Subgrid — это забыть указать, сколько именно рядов или колонок должен занимать дочерний элемент в родительской сетке.
Запомни правило: Subgrid не работает в вакууме. Если ты просто напишешь grid-template-rows: subgrid для карточки, но не укажешь для нее grid-row: span 3 (или точное количество рядов, которое она должна перекрывать), браузер не поймет, к каким именно линиям родительского грида привязывать внутренние элементы. Карточка просто сожмется в один дефолтный ряд, и вся верстка поломается.
Так что всегда четко объявляй диапазон строк или колонок через span для элемента, который использует сабгрид. И будет тебе счастье и идеально ровные макеты без единой строчки JS!
🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!