Перейти к основному содержимому

Адаптивный и отзывчивый дизайн

Разработчику Аналитику Тестировщику
Архитектору Инженеру


Что такое адаптивность​

Play ITЗагрузка интерактивного демо…

Доступность

Учёт "уменьшить движение", контраста и системной тёмной темы — в главе Доступность и пользовательские настройки в CSS.

Логические отступы для RTL — Логические свойства и subgrid.

Шпаргалка

Сводные таблицы "использовать / избегать / осторожно" для вёрстки в целом и для мобильных — в главе Практические рекомендации по CSS.

Семантический каркас без стилей — HTML-страницы целиком.

Адаптив с @media и mobile-first — HTML + CSS — готовые макеты.

Те же breakpoint через префиксы sm:, md:, lg: — Tailwind — готовые блоки.

Анимации — CSS-анимации — готовые эффекты.


Основы​

Адаптивность — это способность веб-страницы автоматически подстраиваться под размер экрана устройства, на котором её открывают.

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

Цель адаптивности — обеспечить удобство использования независимо от устройства:

  • текст читаем без увеличения;
  • кнопки легко нажимать пальцем;
  • изображения не выходят за границы экрана;
  • контент не требует горизонтальной прокрутки.

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

Адаптивность достигается за счёт трёх основных механизмов:

  1. Метатег viewport — сообщает браузеру, как масштабировать страницу на мобильных устройствах.
  2. Медиа-запросы (@media) — позволяют применять разные стили при разных ширинах экрана.
  3. Относительные единицы измерения — делают элементы гибкими, а не фиксированными в пикселях.

Эти инструменты работают вместе. Без viewport медиа-запросы не сработают корректно. Без относительных единиц макет будет "ломаться" при изменении размера.


Ключевые понятия​

Метатег viewport​

На мобильных устройствах браузеры по умолчанию показывают страницу так, будто она открыта на компьютере, а затем уменьшают её, чтобы уместить целиком. Это приводит к мелкому тексту и необходимости масштабировать страницу.

Метатег viewport отключает это поведение:

<meta name="viewport" content="width=device-width, initial-scale=1">
  • width=device-width — делает ширину области просмотра равной ширине экрана устройства.
  • initial-scale=1 — отключает начальное масштабирование.

Этот тег обязателен в каждом современном HTML-документе.

Details

Что такое viewport? Viewport — это видимая область браузера, в которой отображается веб-страница. На мобильных устройствах она отличается от физического размера экрана, если не задан метатег.


Относительные единицы измерения​

Фиксированные значения вроде width: 300px не подходят для адаптивного дизайна. Вместо них используются относительные единицы:

ЕдиницаОписание
%Процент от родительского элемента
emОтносительно размера шрифта текущего элемента
remОтносительно размера шрифта корневого элемента (html)
vw1% от ширины области просмотра
vh1% от высоты области просмотра
chШирина символа "0" в текущем шрифте

Подробный разбор em и rem с числовым примером (как получаются пиксели у заголовков) — в Основных стилях.

Пример:

.container {
width: 100%; /* Занимает всю ширину родителя */
max-width: 1200px; /* Но не больше 1200px */
margin: 0 auto; /* Центрирует блок */
padding: 0 1rem; /* Отступы в rem — масштабируются с шрифтом */
}

📌 Внимание
Используйте max-width, а не width, чтобы контент не растягивался на огромных экранах.


Медиа-запросы​

Медиа-запросы позволяют применять CSS-правила только при определённых условиях — например, когда ширина экрана меньше 768 пикселей.

Базовый синтаксис:

@media (min-width: 768px) {
/* Стили для планшетов и больше */
}

Обычно применяют подход mobile-first: сначала пишут стили для мобильных устройств, а затем добавляют правила для больших экранов через min-width.

Пример полного адаптивного макета:

Код ITЗагрузка примера кода…

⛔ Осторожно
Не привязывайте точки разрыва к конкретным устройствам (например, "768px = iPad"). Лучше выбирать их по содержимому: когда макет перестаёт быть удобным.


Гибкие макеты — Flexbox и Grid​

Современные CSS-технологии — Flexbox и CSS Grid — позволяют создавать макеты, которые сами перестраиваются при изменении ширины.

Пример с Flexbox:

Код ITЗагрузка примера кода…

Преимущество: не нужно использовать float или nth-child для сброса отступов.


Контекст использования​

Адаптивность — это не только про ширину экрана. Также учитываются:

  • Способ взаимодействия: сенсорный экран требует крупных зон нажатия (минимум 48×48 CSS-пикселей).
  • Ориентация устройства: портретная vs альбомная.
  • Плотность пикселей: не влияет на CSS, но важна для изображений (используйте srcset).
  • Системные настройки: тёмная тема, уменьшенные анимации.

Пример учёта предпочтений пользователя:

Код ITЗагрузка примера кода…

Эти медиа-запросы не обязательны для базовой адаптивности, но делают интерфейс более дружелюбным.


Динамические изменения​

Viewport может меняться в реальном времени:

  • при повороте устройства;
  • при скрытии адресной строки в мобильном браузере;
  • при открытии клавиатуры.

Поэтому важно:

  • избегать height: 100vh — используйте 100dvh (dynamic viewport height) или height: stretch в Flex/Grid;
  • не использовать width: 100vw — оно может вызывать горизонтальный скролл из-за системных панелей.

Пример безопасного full-width блока:

.full-width {
width: 100%;
margin-left: calc(-50vw + 50%);
margin-right: calc(-50vw + 50%);
}

Или проще — используйте width: stretch внутри flex-контейнера.


Добавление адаптивности​

Шаг 1. Добавьте метатег viewport​

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

Добавьте в <head> HTML-документа:

<meta name="viewport" content="width=device-width, initial-scale=1">

📌 Внимание
Этот тег обязателен. Без него медиа-запросы могут работать некорректно.


Шаг 2. Используйте относительные единицы вместо фиксированных​

Замените px на относительные единицы:

  • ширина контейнеров → % или max-width
  • отступы и размеры → rem, em
  • полноразмерные элементы → vw, vh (осторожно)

Пример:

.container {
width: 100%;
max-width: 1200px; /* Не больше 1200px */
margin: 0 auto; /* Центрирует */
padding: 0 1rem; /* Отступы масштабируются */
}

💡 Совет
max-width защищает от растягивания на огромных экранах. Без него текст может занимать всю ширину 4K-монитора — и стать нечитаемым.


Шаг 3. Применяйте подход mobile-first​

Начинайте писать CSS с мобильной версии. Это означает:

  • базовые стили — для малых экранов (до 768px);
  • расширения — через @media (min-width: ...).

Пример:

Код ITЗагрузка примера кода…

⛔ Осторожно
Не используйте max-width в медиа-запросах при mobile-first. Это нарушает логику нарастания сложности.


Шаг 4. Сделайте изображения гибкими​

Изображения часто ломают макет, выходя за границы экрана. Исправьте это:

img {
max-width: 100%;
height: auto;
}

Теперь любое изображение будет масштабироваться, но не превысит ширину своего контейнера.


Шаг 5. Используйте Flexbox или Grid для макета​

Эти технологии позволяют создавать гибкие сетки, которые сами перестраиваются.

Пример с Flexbox:

Код ITЗагрузка примера кода…

Преимущество — не нужно использовать float, clear, nth-child.


Шаг 6. Ограничьте ширину текста​

Длинные строки утомляют глаза. Оптимальная длина — 45–75 символов.

Способы ограничения:

  • max-width: 65ch — ch = ширина символа "0"
  • max-width: 800px — фиксированное значение

Пример:

p {
max-width: 65ch;
line-height: 1.6;
}

Шаг 7. Убедитесь, что нет горизонтального скролла​

Горизонтальный скролл — главный признак неправильной адаптивности. Проверьте:

  • все блоки имеют width ≤ 100%;
  • нет margin, padding или border, выталкивающих элемент за край;
  • изображения и видео — гибкие (max-width: 100%);
  • не используется width: 100vw (оно включает системные панели).

💡 Совет
В браузере откройте DevTools → Toggle device toolbar → выберите iPhone SE (320px). Если появился горизонтальный скролл — ищите виновника.


Шаг 8. Проверьте зоны нажатия​

На сенсорных экранах кнопки и ссылки должны быть не меньше 48×48 CSS-пикселей. Это требование доступности.

Пример:

button, a {
min-height: 48px;
min-width: 48px;
padding: 12px;
}

Шаг 9. Тестируйте на реальных устройствах​

DevTools — удобный инструмент, но он не заменяет реальное устройство. Обязательно проверьте:

  • на своём смартфоне (в обычном браузере, не в Telegram/Instagram);
  • в альбомной ориентации;
  • после поворота экрана;
  • при открытии клавиатуры.

Шаг 10. По желанию — добавьте современные улучшения​

Когда базовая адаптивность работает, можно улучшить опыт:

  • Плавное масштабирование текста:
h1 { font-size: clamp(1.5rem, 4vw, 3rem); }
  • Контейнерные запросы (для компонентов):
.card { container-type: inline-size; }
@container (min-width: 300px) { .card__title { font-size: 1.25rem; } }
  • Container scroll-state queries (состояние прокрутки без JS):
.section-header {
position: sticky;
top: 0;
container-type: scroll-state;
container-name: sticky-hd;
}

@container sticky-hd scroll-state(stuck: top) {
.section-header {
box-shadow: 0 2px 8px rgb(0 0 0 / 0.12);
background: var(--surface, #fff);
}
}

Поддерживаемые состояния:

  • stuck — элемент со sticky "прилип" к краю;

  • snapped — элемент зафиксирован через scroll snap;

  • scrollable — контейнер имеет прокручиваемую область.
    Это позволяет убирать JS-обработчики scroll и переносить логику в CSS.

  • Учёт системных настроек:

@media (prefers-color-scheme: dark) { :root { --bg: #121212; } }

Эти шаги не обязательны для базовой адаптивности, но делают интерфейс современнее.