Согласование вложенных сеток с subgrid
В обычной сетке карточки могут иметь одинаковую общую высоту, но их внутренние элементы не обязательно совпадают по горизонтали. Длинное название занимает две строки и сдвигает описание вниз только в своей карточке. Соседняя подпись количества оказывается выше, хотя сами границы выровнены. subgrid позволяет вложенной сетке использовать ряды родителя, чтобы содержимое соседних карточек участвовало в одной системе размеров.
Продолжим те же шесть курсов. В этом уроке сознательно заменим горизонтальный вариант карточки из запроса контейнера пятнадцатого урока. Новый результат — четыре согласованных ряда: обложка, название, описание и метаданные. Самостоятельная сетка каждой карточки останется базовым вариантом там, где subgrid не поддерживается.
Сначала самостоятельные внутренние ряды
Откройте styles.css после предыдущего урока. В слое components полностью удалите прежний блок @container course (min-width: 32rem). В правиле .course-slot удалите container-type и container-name. Мы выбираем другую архитектуру каталога; если оставить обе схемы, широкий компонент одновременно получит горизонтальные столбцы и новые общие ряды.
Замените правила .course-slot, .course-card и .course-card > * + * следующими. Цвет выделенной границы продолжает жить в variants, поэтому в новый общий блок его не переносим. Список сохраняет адаптивные столбцы из предыдущих уроков.
@layer components {
.layout-lab .course-slot { min-inline-size: 0; display: grid; }
.layout-lab .course-card {
display: grid;
grid-template-rows: auto auto 1fr auto;
gap: .75rem;
align-content: start;
block-size: 100%;
padding-block: 1.25rem;
padding-inline: 1.25rem;
background: var(--lab-surface);
border: 1px solid var(--lab-line);
border-radius: .5rem;
}
.layout-lab .course-card > * + * { margin-block-start: 0; }
}
У каждой карточки ожидаются собственные четыре ряда. Первые два и последний получают размер от содержимого, а третий может занять оставшееся пространство растянутой карточки. Прежние внешние отступы между детьми обнулены: расстояние теперь задаёт gap. Если сохранить и отступы, и промежуток сетки, свободное место окажется суммой двух разных механизмов.
Этот вариант уже показывает все курсы. Длинное название не обрезается ради выравнивания, а описание не получает фиксированную высоту в пикселях. Однако самостоятельная карточка по-прежнему вычисляет ряды независимо от соседей. Теперь добавим условное улучшение, которое изменит именно эту зависимость.
Передача рядов через обёртку списка
Добавьте в конец файла следующий полный блок. Он вновь открывает components, а условие ограничивает использование новой схемы поддерживаемым значением свойства.
@layer components {
@supports (grid-template-rows: subgrid) {
.layout-lab .course-slot { grid-row: span 4; grid-template-rows: subgrid; }
.layout-lab .course-card { grid-row: 1 / -1; grid-template-rows: subgrid; }
}
}
Здесь два уровня вложенности: непосредственным элементом внешней сетки является li.course-slot, а внутри него находится article.course-card. Поэтому недостаточно написать subgrid только на статье. Обёртка сначала занимает четыре родительских ряда и передаёт их внутренней сетке. Статья затем занимает всю полученную высоту между первой и последней линиями и тоже использует эти же ряды.
Четыре ряда соответствуют четырём участвующим в потоке детям. grid-row: span 4 у слота резервирует нужный диапазон во внешней сетке. grid-row: 1 / -1 у статьи обозначает весь доступный диапазон её родителя. Это номера линий конкретного уровня сетки, а не номера карточек. При перестановке курсов каждый слот всё равно получает четыре ряда.
Если позднее появится пятый участвующий ребёнок, прежний диапазон нужно будет пересмотреть. Число четыре описывает текущую структуру компонента, а не универсальную вместимость любой вложенной карточки.
В многостолбцовом каталоге ожидается согласование внутренних полос карточек, стоящих рядом. Высокое название увеличивает общий ряд названий этой группы, поэтому соседнее описание начинается после той же линии. Следующая группа карточек рассчитывает свой диапазон рядов. Мы не заставляем все заголовки всего каталога иметь высоту самого длинного заголовка на странице.
Когда остаётся один столбец, соседних карточек по строке уже нет. Каждая группа четырёх рядов принадлежит одному слоту, и польза совместного выравнивания становится менее заметной. Это нормальное следствие структуры, а не отказ subgrid на телефоне. Основной текст продолжает определять нужную высоту, поэтому увеличенный шрифт не обязан помещаться в заранее установленную полоску.
Содержимое участвует в размере родителя
Вложенные элементы subgrid участвуют в расчёте переданных дорожек. Благодаря этому более длинное описание может увеличить общий ряд, даже находясь глубже в HTML. Речь идёт о выбранной оси: в примере передаются ряды, а столбцы остаются устройством внешнего списка. subgrid можно применять и к столбцам, однако это другая обязанность, которой сейчас не требуется.
Промежутки родителя передаются подрешётке по соответствующей оси, а собственное значение gap может их изменить. Внутри карточки оставлен промежуток .75rem, чтобы текст не разъезжался на полный межкарточный шаг. Такая настройка меняет пространство рядом с линиями, поэтому при диагностике полезно включить показ сетки и рассматривать границы отдельно от текста. Подробности передачи рядов и промежутков объясняет MDN о subgrid.
Не заменяйте обёртку на display: contents исключительно ради обхода одного уровня. Это затронуло бы построение коробок и потребовало бы отдельной проверки семантики списка и доступности в целевых браузерах. У нас есть ясная структура ul, li, article, и два небольших правила передают необходимые линии без удаления коробки слота.
Положение ребёнка в сетке также не должно менять порядок чтения. Мы не перемещаем название ниже метаданных через случайные номера рядов и не делаем обложку кнопкой. Сетка согласует размеры тех элементов, которые уже расположены в логичной последовательности. Визуальное совпадение линий не является доказательством удобного клавиатурного маршрута.
Наблюдение и запасной вариант
Для отдельного опыта временно увеличьте название первого курса, добавив к нему несколько слов о практике. Ожидается увеличение ряда названий у соседней группы, при этом все ссылки сохраняют прежние адреса. Затем верните исходную подпись: учебные данные серии должны совпадать на следующих шагах. Сам текст ссылки не управляет URL назначения.
Чтобы посмотреть базовую схему, временно отключите только блок @supports. Ожидаются по-прежнему шесть карточек, но внутренние ряды рассчитываются самостоятельно. Это более полезная проверка, чем отключение всего stylesheet: мы рассматриваем конкретный контракт улучшения. В основном снимке условный блок сохраняется, а диагностическое отключение не записывается как постоянное состояние.
Условие @supports означает распознавание нужного значения движком, а не обещает отсутствие всех ошибок отображения. Перед выпуском всё равно потребуется ручное открытие реального каталога, увеличение текста и просмотр нескольких ширин. При подготовке урока эти опыты не запускались; их ожидаемые эффекты следуют из сохранённой структуры и должны быть сверены отдельно.
Теперь карточки сохраняют гибкую высоту, а соседние элементы могут пользоваться общей системой рядов. Следующая задача касается того, как сам текст участвует в минимальном и максимальном размере коробки. Это поможет понять, почему длинное слово иногда удерживает сетку шире доступного места.
Полное состояние этого шага находится в layout-lab/lesson-19 внутри исходников продолжения. Каждый снимок открывается отдельно; подключать CSS разных уроков одновременно не нужно.