Вписывание изображений
Внешнее окно обложки теперь имеет широкий формат, но исходный рисунок может быть вертикальным. Растянуть его пиксели независимо по двум осям легко, однако круги превратятся в овалы. object-fit выбирает, как содержимое заменяемого элемента вписывается в его коробку: целиком, с обрезанием или другими способами. object-position отдельно определяет положение содержимого внутри этой коробки.
Продолжим обычную сетку с рамкой шестнадцать к девяти. У первого курса заменим только декоративный источник на SVG размером 640 на 800. Все шесть названий, количества и адреса остаются прежними. Результат — картинка заполняет широкую рамку без изменения своих исходных пропорций, а различие cover и contain становится видимым на понятном примере.
Коробка картинки получает два размера
В первой карточке внутри div.course-media замените изображение следующим. Остальные пять картинок сохраняют исходный широкий файл. Новый файл входит в снимок этого урока и содержит простую декоративную геометрию, поэтому пустой alt остаётся осмысленным.
<img class="course-cover" src="assets/course-cover-portrait.svg"
alt="" width="640" height="800">
Важно обновить оба числовых атрибута вместе с источником. Они больше не должны утверждать отношение старого широкого файла. CSS-рамка по-прежнему имеет свой широкий формат, поэтому разные отношения источника и компонента теперь выражены явно. Изменение числа в HTML не означает, что картинка обязана показываться на экране размером 640 на 800.
В конец stylesheet добавьте следующий блок. Он действует при поддержке обоих нужных значений: отношения рамки и режима вписывания. Базовый вариант продолжает показывать полное изображение с автоматической высотой. Существующее правило ширины картинки из предыдущего урока сохраняется.
@layer components {
@supports (aspect-ratio: 16 / 9) and (object-fit: cover) {
.layout-lab .course-media { position: relative; overflow: hidden; }
.layout-lab .course-media .course-cover { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; object-position: 50% 50%; }
}
}
Теперь CSS-коробка картинки занимает ширину и высоту рамки. Содержимое внутри неё вписывается по cover, а положение задано по центру. Ожидается заполнение всей широкой области с обрезанием верхней и нижней части вертикального рисунка. Круг в источнике остаётся кругом в показываемом масштабе: выбран один общий коэффициент масштабирования, а не отдельная растяжка каждой оси.
Картинка внутри поддерживаемой рамки позиционирована абсолютно, а сама рамка стала её локальной опорой. Так природная высота вертикального источника не увеличивает минимальный размер рамки через обычный поток. Место резервирует её собственное отношение сторон. Обрезание ограничено декоративной областью без ссылок; полная карточка и фокус её заголовка не скрываются. Без условного блока картинка остаётся в потоке. Связь предпочтительного отношения с автоматическим минимумом раскрывает текущий проект спецификации CSS Sizing.
Заполнить окно или сохранить весь рисунок
cover выбирает масштаб, достаточный для покрытия обеих сторон коробки. Лишняя часть изображения может выйти за показываемую область содержимого элемента. contain выбирает масштаб, при котором весь рисунок помещается внутри обеих сторон; тогда свободные полосы могут остаться сбоку или сверху. Оба способа сохраняют исходное отношение, но выполняют разные обязанности.
Для отдельного опыта временно замените только cover на contain. У первой вертикальной картинки ожидается полный рисунок с пустым пространством по сторонам. Фон рамки поможет увидеть свободное место. У пяти широких изображений различие может быть почти незаметно, потому что их отношение совпадает с рамкой. Именно поэтому в этом уроке нужен источник другого формата.
После наблюдения верните cover, чтобы основная линия серии показывала выбранное заполнение. Это не универсальное правило для всех учебных иллюстраций. Если рисунок содержит подписи, схему или существенную деталь у края, кадрирование способно потерять информацию. Тогда полное вписывание или обычная автоматическая высота может быть правильнее декоративного одинакового окна.
fill допускает заполнение коробки без сохранения пропорций, поэтому наше несовпадение форматов станет заметным искажением. Значение none не масштабирует объект для подгонки, а scale-down выбирает меньший вариант между отсутствием подгонки и вписыванием. Их можно изучать отдельно, но в основной карточке остаётся один ясно названный выбор. Не смешивайте все значения в накопленных правилах одного элемента.
Обязанности режимов приведены в MDN об object-fit. Свойство действует на содержимое подходящего заменяемого элемента, например изображения, а не на любое нарисованное фоном содержимое. Если обложка задана через background-image, у неё будет другая группа свойств. Перенос изображения в фон также затронул бы его семантику, поэтому сейчас этого не делаем.
Числовой пример без измерения браузера
Предположим рамку размером триста двадцать на сто восемьдесят пикселей и вертикальный источник 640 на 800. Для cover масштаб по ширине равен одной второй, а по высоте — меньшему числу. Выбирается больший масштаб, чтобы закрыть обе стороны. Получается рисунок триста двадцать на четыреста; лишние двести двадцать пикселей высоты не помещаются в показываемой области.
Для contain выбирается масштаб по высоте: сто восемьдесят делится на восемьсот. Рисунок получает размер сто сорок четыре на сто восемьдесят. По горизонтали остаётся свободное место суммарной шириной сто семьдесят шесть пикселей. При центральном положении оно распределяется между двумя сторонами. Это расчёт по выбранным числам, а не полученные значения реальной карточки.
В настоящей сетке ширина зависит от количества колонок и промежутков, а значения могут быть дробными. Нам не требуется вручную округлять изображение под каждую ширину. Расчёт нужен для понимания выбранного режима: какая сторона определяет масштаб и где возникает лишнее место. Браузер затем применяет ту же обязанность к текущей коробке.
Положение объекта не меняет масштаб
object-position: 50% 50% задаёт центральное положение. Для временного опыта измените его на 50% 20%, сохраняя cover. Ожидается изменение вертикального размещения рисунка, благодаря которому верхняя зелёная фигура может стать виднее. Сам масштаб и размер коробки не должны измениться из-за одной этой правки. Затем верните центр, принятый в основном снимке.
Проценты здесь относятся к согласованию позиции внутри имеющегося пространства, а не просто к буквальному отступу в двадцать процентов ширины карточки. Когда объект больше коробки, свободное пространство по соответствующей оси отрицательное, и позиция управляет кадрированием. Поэтому подбор полезно связывать с конкретной важной частью иллюстрации, а не считать процент координатой видимой точки без расчёта.
В нашем источнике все фигуры декоративные, и обрезание не меняет информацию о курсе. Для портрета автора или схемы такой вывод нельзя переносить автоматически. Если разные изображения имеют разные смысловые центры, одной глобальной позиции может быть недостаточно. Тогда нужны данные позиции для конкретного источника либо другой формат компонента с меньшим риском потери содержания.
Базовый вариант сохраняет весь источник
Условный блок оставляет автоматическую высоту там, где рамка не поддерживается. Первая карточка в таком состоянии может стать выше из-за вертикального рисунка. Это допустимое отличие: все пиксели доступны, текст и ссылка сохраняются. Мы не обещаем одинаковый размер карточек при отсутствии всех новых свойств и не скрываем источник ради искусственного совпадения.
Позже проверьте отключённую картинку, несколько ширин и состояние без условного блока. Для учебной статьи ожидаемые результаты изложены по сохранённому коду; реальные браузерные опыты пока не выполнялись. В следующем уроке расширим взаимодействие страницы небольшим нативным диалогом, сохранив обычное объяснение доступным даже без нового API.
Полное состояние этого шага находится в layout-lab/lesson-28 внутри исходников продолжения. Каждый снимок открывается отдельно; подключать CSS разных уроков одновременно не нужно.