CSS · Адаптивная верстка
Castaway: исправляем адаптивную верстку — от проблемы к результату
Автор: Grundy · Проверено: 6 октября 2026
Этот разбор описывает реальные изменения учебной Castaway. Сначала измерили переполнение и изучили ограничения CSS, затем исправили демонстрацию и повторили проверку. Ниже — проблема, причина, внесенное изменение и результат. Кодовые фрагменты сокращены до существенных правил; обновленную страницу можно открыть по ссылке в конце.
1. Зафиксировали переполнение
До исправлений ширина страницы при окне 375px достигала 935px. При 768px она оставалась 935px. Самые широкие блоки — эпизоды, контактная панель и отзывы. Причина не сводилась к одному элементу: фиксированные поля по 70px, горизонтальные flex-карточки и три колонки отзывов не помещались вместе. Исходная сетка ниже требовала минимум 790px еще до учета полей.
.reviews {
display: grid;
grid-template-columns: repeat(3, minmax(250px, 1fr));
gap: 20px;
}2. Уменьшили поля секций
В section.module.css заменили фиксированные padding-left и padding-right на padding-inline с clamp. Поля теперь уменьшаются до 16px и растут до 70px. Для верхних отступов секций на узком экране добавили отдельное значение 56px. Это дало содержимому пространство вместо попытки скрыть переполнение через overflow-x: hidden.
.section {
padding-inline: clamp(16px, 5vw, 70px);
}3. Перестроили hero и вернули ссылки в поток
Hero оставался горизонтальным, а блок Listen on был сдвинут вниз через top: 74px. До 900px перевели hero в колонку, дали дочерним элементам min-width: 0 и убрали относительный сдвиг ссылок. Ширина фотографии теперь ограничена контейнером, декор больше не выходит влево на узком экране.
.hero { gap: clamp(24px, 4vw, 60px); }
.hero > * { min-width: 0; }
.listenOn { position: static; padding-left: 0; margin-top: 32px; }
@media (max-width: 900px) {
.hero { flex-direction: column; align-items: stretch; }
.underline { width: 100%; height: auto; }
}4. Исправили размеры заголовков вместе со span
Размер hero был 70px, вложенные фрагменты — 75px и 80px. Уменьшение одного родителя не исправляло бы вложенные размеры. Заменили размеры на clamp и наследование, line-height сделали относительным. Аналогично уменьшили заголовки эпизодов, автора и подписки. Декоративное подчеркивание на узком экране также масштабируется.
.heroTitle {
font-size: clamp(2rem, 1rem + 4vw, 4.375rem);
line-height: 1.2;
letter-spacing: 0.03em;
}
.heroTitle_bold, .heroTitle_span {
font-size: inherit;
letter-spacing: inherit;
}5. Устранили ограничения карточек и ошибку gap
В карточках стояли несжимаемые изображения, промежуток 53px и отступ 40px. Сделали изображение гибким, тексту добавили min-width: 0, до 900px перевели карточку в колонку. В списке эпизодов нашли gap: 80 без единицы — браузер игнорировал значение. Исправили его на 80px, затем задали гибкий промежуток clamp(32px, 6vw, 80px).
.episode { padding: clamp(20px, 3vw, 40px); gap: clamp(24px, 4vw, 53px); }
.content { min-width: 0; }
.image { flex: 0 1 389px; min-width: 0; }
.image img { width: 100%; height: auto; }
@media (max-width: 900px) {
.episode { flex-direction: column; }
.image { flex-basis: auto; width: 100%; }
}6. Сохранили три колонки на десктопе и добавили две и одну
Старая сетка всегда требовала три колонки не уже 250px. Сняли жесткую минимальную ширину через minmax(0, 1fr), добавили две колонки до 1100px и одну до 650px. Три колонки на широком экране сохраняют композицию макета. Карточкам уменьшили внутренние поля и размер текста, поэтому перестройка сетки не оставляет слишком крупные отзывы.
.reviews { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1100px) {
.reviews { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 650px) {
.reviews { grid-template-columns: minmax(0, 1fr); }
}7. Сохранили пропорции фотографий
В hero-image.module.css заменили несжимаемую обертку на гибкую, основному фото дали отдельный класс photo с width: 100% и height: auto. Декоративный SVG не получил эти правила. Фотографию автора тоже сделали гибкой, секцию об авторе перестроили в колонку. Размеры next/image сохранены, alt фотографий уточнен, у чистого декора alt пустой.
.heroImageContainer { width: min(100%, 650px); flex: 0 1 50%; }
.photo { width: 100%; height: auto; border-radius: 12px; }
@media (max-width: 900px) { .heroImageContainer { flex: initial; } .cornerImage { top: 0; left: 0; } }8. Доработали подписку и футер
Контактная панель оставалась в ряд, у полей не было ограничения по ширине, а неразрывный пробел в Subscribe for updates препятствовал переносу. Убрали этот пробел, ограничили поля шириной контейнера, разрешили сжатие и перестроили панель до 900px. Футер теперь имеет две колонки до 900px и одну до 500px. Поля и кнопки демонстрационной подписки по-прежнему отключены.
.title, .form { min-width: 0; flex: 1; }
.input { width: 100%; min-width: 0; }
@media (max-width: 900px) { .panel { flex-direction: column; } }10. Сравнили результат с исходной проверкой
После исправления проверили 320px, 375px, 768px, 900px, 1024px и 1440px. На всех этих ширинах scrollWidth страницы совпал с clientWidth: горизонтальная прокрутка устранена без ее принудительного скрытия. Проверили нативное открытие меню и закрытие по Escape с возвратом фокуса. Таблица ниже содержит измерения до и после в одном браузере; доступная ширина меньше окна на 15px из-за полосы прокрутки. Это проверка указанных размеров, а не заявление о тестировании всех устройств.
| Окно | Доступно | До | После |
|---|---|---|---|
| 375 | 360 | 935 | 360 |
| 768 | 753 | 935 | 753 |
| 1024 | 1009 | 1009 | 1009 |
| 1440 | 1425 | 1425 | 1425 |