Перейти к содержанию

Позиционирование элементов

Первый курс выделен цветом рамки, но можно дополнительно дать ему небольшую текстовую метку «С чего начать». Она относится к карточке и должна располагаться возле её края, не становясь отдельным рядом каталога. Позиционирование помогает выразить эту связь, если мы понимаем, относительно какой коробки вычисляются координаты.

Продолжим layout-lab после настройки гибких размеров. Данные курса и его ссылка остаются прежними. Результат урока — метка у первого курса с зарезервированным местом над обложкой. На этом примере разберём обычный поток, относительное и абсолютное положение, а также разницу между локальной опорой и viewport.

Обычный поток и визуальное смещение

Элемент с обычным position: static участвует в потоке и получает место по правилам своего форматирования. Свойства координат не превращают его автоматически в закреплённый блок. При position: relative коробка продолжает занимать прежнее место, но может быть визуально смещена относительно этого положения. Соседи не начинают вычислять поток заново с учётом такого смещения.

Для временного опыта можно задать заголовку карточки position: relative и небольшой inset-inline-start. Ожидается сдвиг заголовка, а не появление дополнительного отступа у остальных детей. После опыта удалите оба объявления. Наш постоянный заголовок должен оставаться частью согласованного ряда, поэтому декоративный сдвиг текста не станет основой нового макета.

Само position: relative без координат тоже полезно: оно задаёт локальную опору для некоторых позиционированных потомков. В основном примере карточка не будет смещаться. Она лишь станет коробкой, относительно которой метка получает своё место. Эта обязанность отличается от ручного перемещения всей карточки по странице.

Метка вне рядов сетки

В index.html найдите только первую статью с классом course-card--featured. Вставьте следующий span сразу после её открывающего тега и перед обложкой. Другие пять карточек не изменяйте; название, описание и число уроков остаются в прежнем порядке.

<span class="course-badge">С чего начать</span>

В конец styles.css добавьте следующий полный блок внутри переоткрытого слоя. Он задаёт новые свойства положения и уточняет верхний внутренний отступ принятой карточки.

@layer components {
.layout-lab .course-card { position: relative; padding-block-start: 3rem; }
.layout-lab .course-badge { position: absolute; inset-block-start: .75rem; inset-inline-end: .75rem; max-inline-size: calc(100% - 1.5rem); padding-inline: .5rem; background: var(--lab-accent); color: #fff; font-size: .875rem; }
}

Метка ожидается у конца строчной оси, над обложкой первого курса. В обычном русском направлении это верхний правый угол внутренней области карточки. Абсолютный элемент исключён из обычного потока, поэтому не создаёт пятый ряд в схеме subgrid. Четыре участвующих ребёнка остаются обложкой, названием, описанием и метаданными.

Верхний отступ увеличен у всех карточек, а не только у первой. Это сознательный выбор для текущего согласования рядов: места обложек остаются сопоставимы. Метка получает свободную полосу, но не заставляет вычислять высоту строки по своей надписи. Если задача продукта потребует иной плотности, такую полосу можно организовать отдельным настоящим рядом; здесь изучаем положение вне потока.

Коробка, относительно которой считается координата

Для абсолютного элемента опорой часто становится padding box ближайшего подходящего позиционированного предка. У нас это .course-card с position: relative. Если убрать это свойство, поиск подходящей опоры продолжится выше по дереву, и метка может оказаться у другой коробки. HTML-вложенность сама по себе не обещает, что координаты будут отсчитываться от непосредственного родителя.

Термин containing block обозначает именно опорную область вычисления размеров и положения. Он не обязательно совпадает с видимой рамкой родителя. На его выбор влияют тип позиционирования и некоторые другие свойства предков. Поэтому правило «абсолютный элемент всегда относительно родителя» слишком грубо и ломается при первой дополнительной обёртке. Подробный разбор опоры приведён в MDN о containing block.

Логические inset-block-start и inset-inline-end продолжают модель предыдущих уроков. Для основного горизонтального документа они соответствуют верхней стороне и концу строки. Если направление письма изменится, конец строки может оказаться слева. Мы не добавляем одновременно физические right и логические координаты, чтобы две системы не задавали неожиданно разные стороны.

Максимальная ширина метки ограничена размером карточки за вычетом двух небольших полей. Это не гарантирует, что произвольная длинная надпись поместится в выделенную полосу по высоте. Для нашей короткой подписи место выбрано явно. При локализации или изменении текста нужно снова проверить перенос и высоту; абсолютный элемент не увеличит родительскую полосу самостоятельно.

Почему fixed не означает локальную метку

Значение fixed обычно связывает элемент с viewport, поэтому он может оставаться на том же месте во время прокрутки страницы. Для подписи одного курса такое поведение неудобно: метка потеряет видимую связь с карточкой. Закреплённая панель решает другую задачу, и её не следует создавать только потому, что хочется стабильного верхнего угла.

Кроме того, некоторые свойства предков, например ненулевой transform, могут изменить опору фиксированного потомка. Поэтому даже правило «fixed всегда относительно окна» имеет важные условия. В основном снимке такие свойства карточке не заданы. Если позже эффект оформления неожиданно меняет положение панели, нужно проверять цепочку предков, а не только собственные координаты панели.

Проценты в размерах и смещениях тоже используют определённую опору. Их нельзя интерпретировать как проценты случайной видимой карточки без разбора containing block. В нашем основном варианте для координат использованы небольшие значения rem, чтобы связь была яснее. Процентная часть применяется только в ограничении ширины, где речь идёт о доступной ширине выбранной области.

Наблюдение с удалённой опорой

Временно отключите position: relative у карточки, сохраняя абсолютное положение метки. Ожидается поиск другой опорной коробки и возможное перемещение метки за пределы первой карточки. Затем верните свойство. Этот опыт помогает отличить отсутствие нужной опоры от неверного значения отступа. Случайная правка inset-inline-end не исправляет неправильный уровень отсчёта.

Проверьте также, что ссылка названия остаётся обычным доступным элементом и метка её не перекрывает. Текст метки не должен перехватывать всю площадь статьи невидимой коробкой. В нашем примере span содержит только короткую подпись и не имеет обработчика. Страница ещё не получила JavaScript: расположение само по себе не добавляет действие.

Для полноценного интерфейса иногда нужно, чтобы элемент оставался в потоке и только временно закреплялся при прокрутке. Тогда рассмотрим sticky, который будет отдельным уроком. Сейчас главный результат — локальная абсолютная метка с известной опорой и предусмотренным местом. Следующим шагом выясним, почему большое число z-index не всегда позволяет ей перекрыть соседний контекст.

Полное состояние этого шага находится в layout-lab/lesson-22 внутри исходников продолжения. Каждый снимок открывается отдельно; подключать CSS разных уроков одновременно не нужно.

Оглавление курса.