← Все материалы

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 из-за полосы прокрутки. Это проверка указанных размеров, а не заявление о тестировании всех устройств.

Ширина страницы до и после исправлений, px
ОкноДоступноДоПосле
375360935360
768753935753
1024100910091009
1440142514251425