Изображения в карточках курсов
Добавим изображение в карточку курса и зададим его текстовую альтернативу, пропорции и путь к файлу.
В предыдущем уроке названия получили адреса оглавлений. Теперь подготовим общую учебную обложку. Она украшает каталог, но не добавляет информации к названию курса. Такое условие важно заранее: от роли изображения зависит текст alt, а от его пропорций — место, которое оно займёт внутри карточки. Нельзя сначала вставить картинку, а затем автоматически продублировать её имя файла в альтернативе.
Создайте внутри layout-lab папку assets. В ней будет course-cover.svg: простая векторная композиция с символами кода. Один и тот же рисунок используется во всех шести карточках. Это намеренное ограничение примера. Мы изучаем механику элемента изображения, а не создаём шесть разных иллюстраций или систему загрузки медиа.
Ресурс и элемент изображения
Сохраните следующий полный файл assets/course-cover.svg:
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="360" viewBox="0 0 640 360">
<rect width="640" height="360" fill="#252631"/>
<rect x="96" y="72" width="448" height="216" rx="16" fill="#6c43af"/>
<path d="M232 145 185 180l47 35m176-70 47 35-47 35m-65-90-46 110"
fill="none" stroke="#e4e4e4" stroke-width="12"/>
</svg>
В начале каждой article.course-card, перед заголовком, добавьте один элемент:
<img class="course-cover"
src="assets/course-cover.svg"
alt=""
width="640"
height="360">
При открытии документа ожидается одинаковая обложка над каждым названием. Пока CSS не ограничивает ширину, собственный размер может сделать изображение слишком широким для маленького окна. Мы исправим это в уроке о блочной модели. Сейчас такой результат помогает увидеть различие между размером ресурса и ограничением его отображения, а не скрывает его за заранее готовой сеткой.
src указывает ресурс, а width и height описывают его пропорции числовыми значениями в пикселях. У нашего рисунка отношение сторон равно шестнадцати к девяти. CSS позднее сможет уменьшить отображаемую ширину; атрибуты при этом не нужно удалять. Поддерживаемые атрибуты и их назначение приведены в MDN.
Собственный SVG-файл остаётся отдельным документом. Мы подключаем его через img, поэтому его внутренние элементы не становятся обычными дочерними HTML-узлами карточки. Правило .course-cover { color: ... } не перекрасит автоматически каждый path в подключённом файле. Для нашего фиксированного рисунка цвета записаны внутри SVG. Встроенный SVG потребовал бы другого разбора и сейчас не нужен.
Что сообщает альтернативный текст
Пустое значение alt выбрано потому, что декоративная обложка не сообщает о курсе больше, чем соседнее название. Если написать «Статический сайт из Markdown» и на рисунке, и в альтернативе, и в ссылке заголовка, одна и та же информация будет повторяться. Роль изображения определяется контекстом, а не тем, что оно технически является файлом SVG.
Представим другой случай: обложка показывает диаграмму этапов сборки, а текст рядом её не объясняет. Тогда пустой alt уберёт полезное содержание из альтернативного представления. Потребуется кратко сообщить, что именно изображено, а для сложной схемы дать подробное объяснение в соседнем тексте. В нашем каталоге такой диаграммы нет, поэтому не будем выдумывать её описание.
Различайте пустой alt и полное отсутствие атрибута. Пустое значение выражает решение о декоративной роли. Пропуск не сообщает это решение и может привести к чтению имени файла в некоторых условиях. Подробная работа с альтернативами вынесена в отдельный урок доступности. Здесь важно, чтобы код нашего примера соответствовал выбранному содержанию.
Если рисунок должен служить единственной ссылкой, ему потребуется доступное имя, объясняющее переход. У нас ссылка уже находится в заголовке, поэтому обложка не оборачивается отдельным a. Такое устройство оставляет одну явную цель на карточку. Добавление одинаковых переходов на изображение и название возможно, но требует осознанного решения о числе фокусируемых элементов и не помогает текущей учебной задаче.
Пропорции и масштабирование
Сделаем мысленный расчёт. Если CSS позднее уменьшит ширину картинки с шестисот сорока до трёхсот двадцати пикселей и сохранит пропорции, высота станет сто восемьдесят. Это ожидаемое следствие отношения сторон, а не измерение браузера. Если задать произвольную высоту в сто пикселей вместе с этой шириной, рисунок либо растянется, либо потребуется отдельно выбрать способ вписывания.
Свойство object-fit понадобится, когда коробка изображения имеет заданные размеры и нужно решить, как содержимое разместить внутри неё. cover заполняет коробку с возможной обрезкой, contain сохраняет весь рисунок с возможными свободными полосами. Для нашей обложки мы выберем естественную высоту: ни обрезка, ни фиксированная рамка пока не нужны. Это сохраняет простую связь между пропорциями файла и видом карточки.
Не используйте большой растровый файл только ради того, чтобы уменьшить его CSS до маленького размера. Отображение и передача данных решают разные задачи. У векторной обложки геометрия хранится в командах рисования, но это не делает любой SVG автоматически лёгким: внутри могут оказаться встроенные растровые данные или сложные пути. Мы не заявляем измерений скорости, а выбираем небольшой собственный ресурс по устройству примера.
Пропавший файл и работа без изображения
Временно измените путь на assets/missing.svg. Ожидается, что обложка не загрузится, но название, описание и ссылка останутся в HTML. Это полезная проверка зависимости: курс не должен становиться непонятным при отказе медиа. Если важное название существует только внутри рисунка, такая ошибка уберёт главное содержание карточки. Наш текст не зависит от успешной загрузки SVG.
Затем верните правильный путь и попробуйте открыть сам файл изображения отдельно. Если документ есть, а картинка в карточке не появляется, сравните путь относительно index.html, регистр имени и папку снимка. Не нужно сразу переписывать рисунок. Ошибка подключения и ошибка содержимого ресурса имеют разные причины, хотя обе могут выглядеть как пустое место.
В больших каталогах можно рассмотреть отложенную загрузку изображений вне начальной области, но не нужно добавлять её без понимания расположения. Первая видимая обложка и картинка далеко ниже страницы имеют разные условия появления. В нашем небольшом примере оставляем обычную загрузку, чтобы не вводить ещё одну переменную наблюдения. Атрибуты загрузки меняют момент запроса ресурса, но не заменяют его размеры, альтернативный текст и правильный путь. Эти части задачи нужно проверять независимо.
Фоновая картинка CSS подходит другой роли: она участвует в оформлении коробки, но не предоставляет тот же контракт текстовой альтернативы, что img. Если рисунок содержит полезную информацию, переносить его в background ради удобного обрезания недостаточно. Наш декоративный SVG допускает разные варианты представления, однако оставлен в HTML, чтобы можно было разобрать источник, размеры и альтернативу рядом в одном элементе.
Мы подготовили реальные медиа и определили их роль. В финальном каталоге обложки будут уменьшаться по ширине карточек, сохраняя пропорции. Следующий урок добавит другую встроенную возможность HTML — форму, которая собирает значения и демонстрирует их передачу без JavaScript и без обещания настоящей подписки.