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

Сборка каталога на HTML и CSS

Соберём конечный каталог из изученных механизмов и определим, как расширять его без случайных зависимостей.

В серии мы последовательно добавили разметку, ссылки, изображения, форму и оформление. Последний шаг соединяет эти решения в самостоятельную страницу. Итоговый каталог содержит шесть курсов, адаптивную шапку, сетку карточек, учебную заявку и футер. Все данные находятся в HTML, все правила представления — в CSS; для текущего результата JavaScript и сборщик не требуются.

Полный проект соответствует снимку lesson-16 в учебных исходниках. В нём index.html, styles.css, receipt.html и assets/course-cover.svg. Каждый предыдущий снимок тоже самостоятельный. Не подключайте сразу шестнадцать файлов styles.css: в каждом сохранено полное состояние после соответствующего шага, а не отдельное дополнение, которое нужно суммировать с другими снимками.

Что соединено в одном документе

Каркас состоит из шапки, одной основной области и футера. В каталоге используется список: оболочка записи предоставляет контейнер, статья содержит обложку и три текстовых элемента. Название курса является ссылкой на опубликованное оглавление ProfessorWeb. Описание и число уроков остаются текстом, поэтому отказ загрузки обложки не убирает сведения о записи.

Основная сетка управляет числом колонок, Flexbox — короткими группами в шапке и метаданных, обычный поток — большинством текстовых блоков. Запрос контейнера добавляет внутреннюю сетку широкой карточке. Эти механизмы не конкурируют за одну и ту же задачу. Каждый отвечает за свой уровень, и изменение списка не обязано менять устройство формы или навигации.

В окончательный файл добавим композицию страницы:

.layout-lab {
  min-block-size: 100vh;
  display: flex;
  flex-direction: column;
}
.layout-lab .lab-main {
  flex: 1;
}
.layout-lab .lab-intro {
  margin-block-end: 1.5rem;
}
.layout-lab .lab-footer {
  border-block-start: 1px solid var(--lab-line);
}

Ожидается, что при небольшом объёме основное содержимое займёт свободное место и футер окажется у нижней части окна. При длинном каталоге страница сможет увеличиться, а футер останется после содержимого. Минимальный размер выбран вместо фиксированной высоты: он не запрещает документу стать выше viewport. Это продолжение flex-компоновки, а не закрепление футера поверх текста.

На мобильных устройствах единица vh связана с особенностями viewport и браузерных панелей. Для конкретного продукта можно рассмотреть современные варианты единиц, но их выбор требует отдельной проверки среды. В нашем учебном макете не объявляем одинаковое поведение каждой панели браузера. Важный результат здесь — отсутствие абсолютного футера, который мог бы закрывать последний абзац.

Печатное представление

Каталог можно сделать пригоднее для простого печатного просмотра без изменения HTML. Добавьте отдельное условие:

@media print {
  .layout-lab {
    background: #fff;
    color: #111;
    display: block;
  }
  .layout-lab .course-card {
    background: #fff;
    border-color: #aaa;
    break-inside: avoid;
  }
  .layout-lab a,
  .layout-lab .course-count { color: #111; }
  .layout-lab .lab-request,
  .layout-lab .lab-nav { display: none; }
}

Ожидается светлое представление без формы и служебной навигации. Содержание курсов остаётся. break-inside выражает пожелание избежать разрыва карточки, но очень большой блок или особенности печати могут ограничить результат. Нельзя выдавать такое объявление за гарантированную пагинацию любого принтера. Само использование среды печати относится к возможностям медиазапросов CSS.

Форма скрывается потому, что её интерактивное действие не выполняется на бумаге. Мы не прячем описания и названия. Такой выбор должен следовать задаче представления. Если печатный каталог должен содержать полные адреса, потребуется отдельное решение; текущий макет сохраняет названия ссылок, но не добавляет их URL после каждого курса. Подробный разбор печати статьи уже есть в соответствующем уроке.

Добавление новой записи

Чтобы добавить седьмой курс, скопируйте один li.course-slot внутри ul.course-list. Измените название, описание, число уроков и адрес оглавления. Если запись не должна быть рекомендованной, уберите course-card--featured. CSS менять не нужно: Grid разместит ещё один элемент, обёртка предоставит тот же контейнер, а внутренние интервалы останутся общими.

Проверьте, действительно ли новый адрес существует. Видимое название не подтверждает правильность href. Не копируйте курс только ради заполнения последней строки: пустая область сетки не является причиной создавать дубли содержания. Автоматическое распределение рассчитано на разное число записей. При изменении смыслового порядка переставьте HTML, чтобы визуальное и исходное чтение продолжали совпадать.

Если новый курс имеет собственную обложку, сохраните файл в assets и обновите src. Уточните пропорции и роль альтернативного текста. Нельзя оставлять размеры старой картинки автоматически, если новая имеет другое отношение сторон. В нашем текущем наборе общая декоративная обложка использует пустой alt, но это решение не переносится без анализа на любую будущую диаграмму.

Ручная приёмка перед выпуском

Откройте конечный index.html и сравните шесть записей с исходными данными. Затем постепенно меняйте ширину окна, увеличивайте текст и вводите длинное название. Ожидается сохранение содержания без наложений. Проверьте клавиатурные переходы, форму с пустым и заполненным вымышленным именем, раскрытие пояснения. Полученные наблюдения нужно записать отдельно: в этой серии описаны ожидаемые результаты, а программы и браузерный макет при подготовке не запускались.

Уберите временно файл стилей и убедитесь, что порядок и смысл остаются ясными. Затем восстановите его. Если каталог читается только благодаря расположению, пересмотрите HTML. CSS должен улучшать представление уже осмысленного документа. Это особенно важно при отказе ресурсов, альтернативном чтении и будущей переделке дизайна.

Сведения о числе уроков в нашем HTML являются снимком данных. При расширении настоящего курса их потребуется обновить вручную, если каталог останется полностью ручным. Это ограничение связано с источником данных, а не с CSS Grid. В будущем генератор может получать эти числа из Markdown и списка маршрутов, сохранив ту же разметку карточек. Такой перенос не требует заново изобретать блочную модель.

Также отделяйте самостоятельный учебный проект от действующего сайта. Копирование полного body внутрь общей статьи не является интеграцией шаблона. Для настоящего ProfessorWeb нужно использовать общий хедер, футер и метаданные, а содержимое каталога вставлять в предусмотренную область. Здесь мы изучали автономную страницу, чтобы видеть действие каждого механизма без внешних зависимостей.

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

Редактор может отдельно записать браузер, размер окна и полученные наблюдения. Эти записи сделают проверку воспроизводимой для следующего автора. Отсутствие автоматических тестов не означает, что результат следует объявлять правильным без наблюдения: на текущем этапе это подготовленные материалы и исходники для ручной приёмки.

Финальный проект намеренно не содержит поиска, авторизации и настоящей подписки. Такие функции добавляют собственные данные и состояния, а не появляются от наличия готовых полей. Дальше можно перенести список курсов в генератор статического сайта или подключить поиск отдельным курсом. Основой останутся изученные отношения: структура документа, управляемый каскад, размеры коробок и независимые уровни компоновки.

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