3.10. Адаптивность
Разработчику
Аналитику
Тестировщику
Архитектору
Инженеру
Адаптивность
Адаптивность в веб-разработке — это свойство пользовательского интерфейса подстраиваться под различные условия отображения: размеры экрана, разрешение, плотность пикселей, ориентацию устройства, а также особенности взаимодействия (управление сенсорным вводом, клавиатурой, указателем). Это системный подход к проектированию и реализации интерфейсов, в котором участвуют HTML, CSS, JavaScript, а также методологии проектирования и тестирования.
В основе адаптивного подхода лежит отказ от жёсткой привязки макета к конкретному разрешению или устройству. Вместо этого интерфейс строится как набор гибких, масштабируемых и перестраиваемых компонентов, поведение которых регулируется в зависимости от доступного пространства. Такой подход обеспечивает стабильность восприятия интерфейса и сохранение функциональности независимо от среды просмотра.
Исторически первоначальные веб-страницы разрабатывались исключительно для настольных экранов. С появлением смартфонов и планшетов стало очевидно, что универсальный подход к верстке недостаточен: фиксированные макеты в 960 или 1024 пикселей по ширине оказывались непригодны для экранов шириной 320–414 пикселей. Возникло два направления решения проблемы: отдельные мобильные версии сайтов (часто по адресу m.example.com) и адаптивный дизайн (Responsive Web Design, RWD), впервые систематически описанный Итаном Марком (Ethan Marcotte) в 2010 году. Второй подход быстро стал доминирующим, поскольку исключает дублирование контента, упрощает поддержку и обеспечивает единый URL для всех устройств — что важно как для пользовательского опыта, так и для поисковой оптимизации.
Современное понимание адаптивности выходит за рамки лишь визуального масштабирования. Оно включает:
- динамическое изменение структуры и иерархии элементов (например, сворачивание навигации в гамбургер-меню);
- адаптацию типографики (размер шрифта, межстрочный интервал, длина строки);
- перераспределение нагрузки на интерфейс (скрытие несущественных элементов на малых экранах, замена тяжёлых визуальных компонентов на упрощённые аналоги);
- учёт контекста использования (в том числе освещённости, скорости соединения, энергетического профиля устройства);
- обеспечение доступности при масштабировании и изменении ориентации.
Для реализации адаптивного поведения в HTML и CSS задействуется ряд взаимосвязанных механизмов, главными из которых являются метатег viewport, медиа-запросы (@media), относительные единицы измерения (em, rem, vw, vh, %), гибкие макетные технологии (Flexbox, CSS Grid), а также современные CSS-возможности — контейнерные запросы (@container), clamp(), env() и CSS-переменные. Взаимодействие этих инструментов образует стройную систему, где каждая составляющая отвечает за конкретный аспект адаптации.
Что такое адаптивность в техническом контексте
Адаптивность — это свойство системы отвечать на изменения внешних параметров так, чтобы сохранить целостность функционального и визуального опыта. В контексте CSS под адаптивностью обычно подразумевается отзывчивый макет (responsive layout) — макет, способный плавно или дискретно изменять своё поведение в ответ на изменение ширины области просмотра (viewport). Однако следует различать термины:
- Responsive design (отзывчивый дизайн) — подход, при котором макет изменяется непрерывно или по заданным точкам разрыва (breakpoints) в зависимости от ширины viewport. Реализуется преимущественно с помощью медиа-запросов и относительных единиц.
- Adaptive design (адаптивный дизайн в узком смысле) — подход, при котором сервер или клиент выбирает одну из нескольких предопределённых версий интерфейса, исходя из данных об устройстве (например, по User-Agent или feature detection). Такой подход требует отдельных шаблонов под каждое «окно» разрешений.
- Fluid design (резиновый/гибкий дизайн) — макет, построенный на относительных единицах (
%,vw), который масштабируется плавно без явных точек разрыва.
Современная практика чаще всего сочетает все три подхода: плавное масштабирование базовой структуры (fluid), дискретные перестроения при переходе между ключевыми размерами (responsive), и частичную адаптацию под возможности устройства (adaptive features, например, использование prefers-reduced-motion или prefers-color-scheme).
Ключевой ошибкой при реализации адаптивности является попытка сопоставить точки разрыва с конкретными моделями устройств — например, «768px — это iPad». Подобное мышление быстро устаревает, поскольку рынок устройств динамичен: появляются складные экраны, планшеты с нестандартным соотношением сторон, ультраширокие мониторы и даже автомобильные интерфейсы. Поэтому правильнее определять breakpoints не по названию устройств, а по содержимому макета: точка разрыва возникает тогда, когда текущее расположение элементов перестаёт быть функциональным или эстетически приемлемым. Это называется content-based breakpoints.
Как происходит работа над адаптивностью
Работа над адаптивной системой начинается на этапе проектирования. Адаптивность должна быть заложена в концепцию интерфейса, а не добавлена как «последний штрих». Основные этапы:
-
Анализ аудитории и устройств — сбор данных о том, с каких устройств и в каких условиях происходит основное взаимодействие с продуктом. Это помогает определить приоритеты (например, если 85% трафика — мобильный, то разработка ведётся по принципу mobile-first).
-
Разработка дизайн-системы с адаптивными токенами — определение масштабируемой сетки, типографской шкалы, отступов и радиусов, которые легко адаптируются через относительные единицы или CSS-переменные.
-
Создание wireframe’ов и прототипов в нескольких viewport’ах — проверка, как компоненты ведут себя при изменении ширины. Важно отработать горизонтальное перетекание контента: например, как таблица с 12 столбцами отображается на экране шириной 320px.
-
Реализация базовой структуры с использованием семантического HTML и гибких макетов (CSS Grid, Flexbox) — семантическая разметка повышает доступность и упрощает последующую адаптацию через CSS без изменения структуры.
-
Применение медиа-запросов и контекстных правил — добавление точек разрыва только там, где это действительно необходимо. Избыточное количество
@mediaправил усложняет поддержку. -
Тестирование в реальных условиях — на физических устройствах, с учётом скорости сети (например, через throttling в Chrome), уровня заряда батареи, освещённости.
-
Оптимизация производительности на маломощных устройствах — сокращение количества DOM-узлов, упрощение анимаций, исключение тяжёлых шрифтов, отложенный рендеринг изображений.
Весь этот цикл итеративен: по мере выявления проблем в одном сценарии (например, горизонтальный скролл на Android-устройстве с шириной 360px) вносятся корректировки в дизайн-систему, прототипы и код. Важно избегать «точечных» правок — каждое изменение должно согласовываться с общей адаптивной стратегией.
Мобильные устройства и планшеты
Мобильные устройства — это не просто «маленькие экраны». Это целый класс устройств с уникальными характеристиками:
-
Высокая плотность пикселей (device pixel ratio, DPR): физический пиксель на экране может состоять из нескольких аппаратных пикселей (2×, 3×, 4×). Это требует использования векторной графики или изображений в нескольких разрешениях (
srcset,<picture>), но не влияет напрямую на CSS-макет, поскольку CSS-пиксель абстрагирован от аппаратного. -
Сенсорный ввод: минимальная зона нажатия должна составлять не менее 48×48 CSS-пикселей (рекомендация WCAG), интерактивные элементы требуют увеличенных отступов, исключается ховер-состояние как основной способ взаимодействия.
-
Ограничения по ресурсам: процессоры мобильных устройств, особенно бюджетных, значительно уступают десктопным по производительности. Сложные CSS-анимации (
box-shadow,filter,transformбезwill-change), большое количество DOM-узлов или тяжёлые JavaScript-библиотеки могут привести к подтормаживаниям, перерасходу энергии и быстрому разряду аккумулятора. -
Особенности браузерной оболочки: на iOS Safari занимает часть вертикального пространства (адресная строка, панель закладок), которая может появляться и исчезать при прокрутке. Это приводит к изменению высоты viewport в реальном времени —
vh-единицы могут «прыгать», если не учитыватьsvh,lvh,dvh(в современных браузерах) или использовать JavaScript-корректировку.
Планшеты находятся в промежуточной зоне: по размеру они приближаются к ноутбукам, но по способу взаимодействия — к смартфонам. Часто используется гибридный подход: на портретной ориентации планшета сохраняется мобильная навигация (гамбургер), а в альбомной — активируется двухколоночный макет с боковой панелью. Однако не стоит полагаться только на ориентацию (orientation: landscape), так как многие устройства (например, iPad Pro) используют одну и ту же ширину viewport в обеих ориентациях при определённых настройках масштаба.
Огромные мониторы
На другом полюсе находятся ультраширокие и 4K-мониторы. Ширина viewport может превышать 2560px, а иногда — и 5000px. Проблемы здесь иные:
-
Чрезмерная длина строки — при фиксированной ширине
100%текст может растягиваться на 200+ символов в строке, что резко снижает читаемость. Решение — ограничение максимальной ширины контентной области (max-width: 1200px) с выравниванием по центру (margin: 0 auto). -
Пустое пространство по бокам — если не предусмотреть расширяемые элементы (фоновые изображения, full-width секции, анимированные декоративные компоненты), интерфейс выглядит «потерянным» на большом экране.
-
Разрыв единства восприятия — при очень широком экране пользователь вынужден двигать взгляд от левого края к правому, что увеличивает когнитивную нагрузку. В таких случаях оправдано использование многоколоночных макетов или разбиение интерфейса на зоны с фокусировкой на центральной области.
-
Сложности с масштабированием — пользователи с нарушениями зрения могут увеличивать масштаб в браузере до 200–300%. Макет должен оставаться работоспособным и при этом не допускать горизонтального скролла.
Панель инструментов устройства в браузере (DevTools)
Современные браузерные DevTools (в первую очередь — Chrome DevTools, но аналогичные функции присутствуют в Firefox, Edge и Safari) предоставляют комплекс средств для эмуляции и анализа адаптивного поведения. Однако важно понимать: эмуляция — не замена реальному тестированию. DevTools позволяют быстро итерировать и отлаживать, но финальная проверка всегда должна проводиться на физических устройствах.
Центральный инструмент — Device Mode (режим устройства), активируемый кнопкой Toggle device toolbar (значок смартфона/планшета) или сочетанием Ctrl+Shift+M / Cmd+Shift+M. В этом режиме окно просмотра становится регулируемым: его можно изменять вручную, выбирать из списка предустановленных устройств (iPhone, Pixel, iPad и др.), или задавать пользовательские размеры. При этом автоматически включается эмуляция:
- Ширины и высоты viewport — значения, по которым срабатывают медиа-запросы.
- Device Pixel Ratio (DPR) — эмулируется соотношение CSS-пикселя к физическому. Например, при выборе iPhone 13 (DPR = 3) браузер масштабирует отрисовку в 3 раза, что влияет на резкость изображений, но не на CSS-логику.
- User-Agent — отправляется строка, характерная для выбранного устройства. Это важно при server-side detection, но в чистом CSS/JS не используется.
- Touch events — курсор мыши эмулирует сенсорное касание (например, не вызывает
:hoverдо первого клика).
Однако Device Mode не эмулирует:
- производительность процессора и GPU;
- задержки сети (требуется отдельный инструмент — Network Throttling);
- особенности рендеринга на iOS Safari (WebKit имеет отличия от Blink);
- поведение системных элементов (например, скрытия адресной строки при скролле на мобильном Safari).
Для более глубокого анализа применяются следующие панели и функции:
-
Media Query Inspector (вкладка Elements → Styles → значок «медиа» рядом с
@media) — визуализирует все активные и неактивные медиа-запросы на странице, позволяет быстро переключаться между точками разрыва. -
Rendering panel (вкладка More tools → Rendering) — показывает параметры визуализации: FPS, layout shifts, paint flashing, core web vitals. Особенно полезна опция Layout Shift Regions: она подсвечивает элементы, вызывающие сдвиги при загрузке — частую проблему на мобильных устройствах из-за динамически подгружаемого контента (баннеров, шрифтов, изображений без
width/height). -
Coverage tool (вкладка More tools → Coverage или
Ctrl+Shift+P→ «Coverage») — анализирует, какие CSS- и JS-правила были реально использованы при текущем состоянии страницы. Позволяет выявить «мёртвый» код, относящийся к неактивным viewport’ам. -
Device Frame и Sensors — эмуляция датчиков (гироскоп, акселерометр), цветовой схемы (
prefers-color-scheme), режима энергосбережения (prefers-reduced-motion,prefers-reduced-data), уровня заряда. Последнее критично: при уровне заряда < 20% или включённом режиме энергосбережения браузер может приостанавливать анимации, откладывать фоновые задачи, ограничивать частоту обновления — поведение, которое необходимо учитывать при проектировании.
Эффективная работа с DevTools предполагает системный подход: последовательно пройти по контрольным точкам — от минимальной ширины (320px) до максимальной (2560px+), включая переходы через каждую точку разрыва, проверку в альбомной ориентации, имитацию медленного 3G-соединения, включение prefers-reduced-motion и анализ производительности на слабом CPU (через Performance → CPU throttling).
Масштаб и разрешение
Для корректной реализации адаптивности необходимо точно различать три связанных, но независимых понятия:
-
Физическое разрешение экрана — количество аппаратных пикселей по горизонтали и вертикали (например, 1440×3088 для Samsung Galaxy S22 Ultra). Это аппаратный параметр, недоступный напрямую через CSS.
-
CSS-разрешение (viewport width/height) — размер области просмотра в CSS-пикселях. Именно к нему относятся медиа-запросы (
max-width: 768px). Определяется как:CSS-ширина = физическая ширина / devicePixelRatio (DPR)Например, устройство с физическим разрешением 1080px и DPR = 2.5 сообщает CSS-ширину 432px (
1080 / 2.5 = 432). Это значение можно прочитать в JavaScript черезwindow.innerWidthи использовать в медиа-запросах. -
Масштаб (scale factor) — коэффициент увеличения/уменьшения, применяемый браузером к странице. По умолчанию равен 1.0, но может изменяться:
- пользователем (жестом «щипок»);
- системой (автоматическое масштабирование текста в настройках ОС);
- разработчиком (через
initial-scale,minimum-scaleв метатегеviewport).
Метатег viewport управляет именно виртуальным viewport’ом — областью, в которой браузер отрисовывает макет. Без него мобильные браузеры используют layout viewport шириной ~980px, чтобы «вместить» десктопный сайт, но затем уменьшают его до физического viewport’а — отсюда и необходимость горизонтальной прокрутки и ручного масштабирования.
Ключевая директива — width=device-width. Она устанавливает ширину layout viewport равной ширине visual viewport (того, что видит пользователь в текущий момент), что приводит к синхронизации CSS-пикселей с реальными возможностями устройства. После этого медиа-запросы начинают работать ожидаемо: max-width: 768px действительно сработает на iPad и большинстве планшетов.
Важно: device-width — это не постоянная величина. Она меняется при:
- повороте устройства (ширина и высота меняются местами);
- скрытии/появлении системных панелей (адресная строка, клавиатура);
- открытии in-app браузера (например, в Telegram или Instagram), где viewport может быть искусственно ограничен.
Для работы с динамическими изменениями используются:
window.matchMedia()в JavaScript — отслеживание активности медиа-запросов;resizeиorientationchangeсобытия — с осторожностью, из-за частоты вызовов и различий в поддержке;- современные CSS-единицы:
svw/svh(small viewport),lvw/lvh(large viewport),dvh(dynamic viewport height), которые автоматически учитывают видимость системных панелей.
Энергоэффективность, упрощение и сжатие
Адаптивность — не только о внешнем виде. В условиях роста доли мобильного трафика и усиления требований к экологичности цифровых продуктов, энергоэффективность становится обязательной частью адаптивной стратегии. Исследования показывают, что до 20% энергопотребления смартфона приходится на работу браузера, и значительная часть — на рендеринг и JavaScript-исполнение.
CSS оказывает прямое влияние на энергопотребление. Следующие практики позволяют снизить нагрузку на устройство:
1. Минимизация layout thrashing и paint-операций
Каждое изменение геометрии элемента (ширина, высота, margin, padding, font-size) вызывает layout recalculation — пересчёт позиций всех элементов на странице. Это одна из самых дорогих операций. Адаптивные перестроения должны быть:
- редкими (избегать
@mediaна каждый пиксель); - предсказуемыми (использовать
transformиopacityдля анимаций, так как они не вызывают layout); - локализованными (изолировать перестраиваемые компоненты с помощью
contain: layoutилиcontain: strict).
2. Упрощение визуальных эффектов на маломощных устройствах
CSS-свойства box-shadow, filter, backdrop-filter, clip-path требуют значительных вычислений GPU. При обнаружении низкой производительности (например, через navigator.hardwareConcurrency < 4 или navigator.connection.effectiveType === 'slow-2g') можно:
- отключать тяжёлые эффекты через медиа-запросы:
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; }
} - использовать
@media (prefers-reduced-data: reduce)для упрощения графики; - применять
@media (dynamic-range: standard)для отключения HDR-эффектов на устройствах без поддержки.
3. Оптимизация шрифтов
Шрифты — одна из главных причин задержек отрисовки и потребления памяти. Рекомендации:
- использовать
font-display: swap, чтобы текст отображался сразу, даже если шрифт ещё не загружен; - ограничивать количество начертаний (обычно достаточно regular + bold);
- отдавать шрифты в формате WOFF2 с подмножествами (
unicode-range); - избегать
@font-faceвнутри медиа-запросов — это приводит к множественной загрузке одних и тех же файлов.
4. Сжатие и отложенная загрузка ресурсов
Хотя это относится скорее к HTML и JavaScript, CSS может способствовать оптимизации:
- использование
pictureиsrcsetв сочетании с@mediaдля адаптивных изображений:<picture>
<source media="(max-width: 768px)" srcset="small.jpg">
<source media="(min-width: 769px)" srcset="large.jpg">
<img src="fallback.jpg" alt="">
</picture> - применение
loading="lazy"для изображений и iframe вне viewport; - исключение тяжёлых SVG-анимаций на мобильных устройствах через
@media (max-width: 768px) { svg.animated { display: none; } }.
5. Использование CSS-переменных для централизованной адаптации
CSS Custom Properties (переменные) позволяют реализовать динамическую адаптацию без дублирования правил. Например:
:root {
--space-unit: 1rem;
--text-base: 1rem;
--border-radius: 0.375rem;
}
@media (max-width: 767px) {
:root {
--space-unit: 0.75rem;
--text-base: 0.9375rem;
--border-radius: 0.25rem;
}
}
body { font-size: var(--text-base); }
.container { padding: var(--space-unit); }
.card { border-radius: var(--border-radius); }
Такой подход:
- исключает дублирование селекторов;
- позволяет легко менять «масштаб интерфейса» для всего проекта;
- поддерживает темизацию и динамическое переключение через JavaScript (
document.documentElement.style.setProperty('--text-base', '1.125rem')).
Современные расширения адаптивности
Хотя медиа-запросы остаются основным инструментом, развитие CSS привело к появлению механизмов, которые позволяют адаптировать интерфейс под размер окна просмотра (viewport), и под локальный контекст компонента. Это особенно важно в эпоху компонентных архитектур (React, Vue, Web Components), где компонент должен быть самодостаточным и не зависеть от глобальных точек разрыва.
Контейнерные запросы (@container)
Контейнерные запросы — принципиально новый подход, введённый в CSS Containment Module Level 3. Вместо @media (max-width: 768px) разработчик может написать:
.card {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 300px) {
.card__title { font-size: 1.25rem; }
.card__actions { display: flex; gap: 0.75rem; }
}
Здесь .card объявляется как контейнер по ширине (inline-size). Правила внутри @container применяются, когда ширина самого контейнера достигает указанного порога.
Преимущества:
- компоненты становятся независимыми от глобального layout: карточка может перестраиваться как на мобильном экране (если помещается в две колонки), так и в узкой боковой панели десктопного интерфейса;
- устраняется каскадная зависимость от точек разрыва: не нужно знать, при каком
viewportкарточка станет узкой — она реагирует на своё внутреннее состояние; - упрощается дизайн-система: один компонент может использоваться в разных layout’ах без модификации.
Ограничения:
- контейнер должен иметь явно заданную ширину (или наследовать её), иначе
inline-sizeбудет0; - нельзя использовать
container-nameв@mediaи наоборот — это разные системы; - поддержка: Chrome 105+, Firefox 110+, Safari 16.4+. Для продакшена требуется feature detection (например, через
@supports (container-type: inline-size)).
Рекомендуется сочетать @container и @media: глобальные структурные изменения (например, переход от одно- к двухколоночному layout’у) управлять через медиа-запросы, а микронастройки компонентов — через контейнерные.
Функции clamp(), min(), max() как замена множеству точек разрыва
Часто адаптивность сводится к плавному изменению параметров (например, размера шрифта или отступа) в заданном диапазоне. Раньше это требовало нескольких @media, но теперь можно сделать это в одном правиле:
h1 {
font-size: clamp(1.5rem, 4vw, 3rem);
}
Здесь:
1.5rem— минимальное значение (гарантированно читаемо на самых малых экранах);3rem— максимальное значение (не перегружает крупные экраны);4vw— гибкое значение, пропорциональное ширине viewport.
Результат: заголовок масштабируется плавно от 24px (на 320px) до 48px (на 1200px+), без единого медиа-запроса.
Аналогично:
min(100%, 80ch)— ограничивает ширину текстового блока по количеству символов в строке (рекомендовано 45–75 символов для комфортного чтения);max(12px, 0.9em)— гарантирует, что шрифт не станет меньше 12px, даже если родительскийfont-sizeуменьшен.
Эти функции особенно эффективны в сочетании с CSS-переменными:
:root {
--text-scale: clamp(0.875rem, 2.5vw, 1.25rem);
--space-base: clamp(0.75rem, 4vw, 2rem);
}
Такой подход сокращает объём CSS, повышает предсказуемость и устраняет «ступенчатость» изменений.
Относительные единицы: em, rem, ch, ex, cap
Помимо vw/vh, важную роль играют типографические относительные единицы:
em— относительноfont-sizeтекущего элемента;rem— относительноfont-sizeкорневого элемента (html);ch— ширина символа «0» в текущем шрифте (идеальна для ограничения длины строки);ex— высота строчной «x»;cap— высота прописной буквы (например, «H»), появилась в CSS Values 4.
Пример адаптивной типографики на rem:
html {
font-size: clamp(14px, 1.8vw, 18px); /* глобальный масштаб */
}
h2 { font-size: 1.75rem; } /* = 24.5px–31.5px */
p { line-height: 1.6; }
p { max-width: 65ch; } /* ~65 символов в строке */
Это обеспечивает естественную иерархию, устойчивую к изменениям масштаба пользователя (в отличие от px).
Адаптивность вне ширины экрана
Современный CSS позволяет адаптироваться к размеру экрана и к предпочтениям и физиологическим особенностям пользователя. Эти медиа-функции работают через те же @media или @supports, но с другими условиями.
prefers-color-scheme
Позволяет переключать интерфейс между светлой и тёмной темами в соответствии с системными настройками:
@media (prefers-color-scheme: dark) {
:root {
--bg: #121212;
--text: #e0e0e0;
}
}
Важно: не следует насильно навязывать тему при prefers-color-scheme: no-preference. Лучше предложить пользователю выбор и сохранить его в localStorage.
prefers-reduced-motion
Указывает, что пользователь предпочитает минимизировать анимации — часто по медицинским причинам (например, эпилепсия, вестибулярные расстройства):
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.001ms !important;
}
}
Лучше не отключать анимации полностью, а заменять их на мгновенные переходы (например, opacity вместо transform: scale()).
prefers-contrast и forced-colors
prefers-contrast: more— запрос на повышенный контраст (для пользователей с нарушениями зрения);forced-colors: active— браузер принудительно переопределил цвета (например, в режиме Windows High Contrast).
Пример:
@media (prefers-contrast: more) {
:root {
--border: 2px solid;
--focus-outline: 3px solid Highlight;
}
}
@media (forced-colors: active) {
.custom-checkbox {
forced-color-adjust: none; /* разрешаем переопределение */
}
}
any-pointer, any-hover
Определяют типы доступных указателей:
@media (any-pointer: coarse)— есть сенсорный/крупный указатель (требуются увеличенные цели);@media (any-hover: none)— ховер недоступен (не стоит полагаться на:hoverкак на основной способ взаимодействия).
Тестирование и метрики
Адаптивность — не субъективное понятие. Её можно и нужно измерять количественно. Ключевые метрики:
Core Web Vitals (Google)
-
LCP (Largest Contentful Paint) — время отрисовки крупного элемента. На мобильных устройствах из-за медленных сетей и CPU значение часто растёт. Адаптивная оптимизация (ленивая загрузка, упрощение DOM) напрямую влияет на LCP.
-
CLS (Cumulative Layout Shift) — совокупный сдвиг макета. Часто возникает при подгрузке шрифтов, изображений без
width/height, рекламы. Адаптивные блоки должны иметь заранее выделенное пространство (aspect-ratio,min-height). -
INP (Interaction to Next Paint) — замена FID, измеряет отзывчивость на взаимодействие. На слабых устройствах тяжёлые CSS-анимации или JavaScript-обработчики могут резко увеличивать INP.
Доступность (WCAG)
- Уровень контраста текста (минимум 4.5:1 для обычного текста);
- Размер зон нажатия (минимум 24×24 CSS-пикселей для WCAG 2.1, 44×44 для iOS Human Interface Guidelines);
- Соответствие
prefers-*настройкам.
Энергопотребление
Прямое измерение сложно, но косвенные индикаторы:
- количество forced layers (в Rendering panel);
- частота
style recalculationsиlayoutв Performance timeline; - использование
will-changeбез необходимости.
Антисемплы
Ниже — типичные нарушения, ведущие к нестабильной адаптивности.
1. width: 100vw на мобильных устройствах
vw учитывает всю ширину viewport, включая вертикальную полосу прокрутки (если есть) и системные панели. На iOS это приводит к горизонтальному скроллу, даже если элемент один.
Решение: использовать width: 100% или width: stretch (в Flex/Grid), либо width: calc(100vw - env(safe-area-inset-left) - env(safe-area-inset-right)).
2. Отсутствие min-width: 0 в Flex/Grid-контейнерах
По умолчанию flex-элементы имеют min-width: auto, что предотвращает их сжатие меньше содержимого. На малых экранах это вызывает переполнение.
Решение:
.card { min-width: 0; } /* для flex-дочерних */
.grid-item { min-width: 0; } /* для grid-дочерних */
3. height: 100vh на мобильных Safari
Из-за динамического изменения высоты viewport (при скрытии адресной строки) 100vh фиксируется на максимальном значении, вызывая «прыгающий» контент.
Решение: использовать height: 100dvh (dynamic viewport height) или height: stretch в flex-контейнере. При отсутствии поддержки — JavaScript-коррекция.
4. Медиа-запросы без min-width в mobile-first подходе
/* Плохо: нарушает каскад */
@media (max-width: 768px) { ... }
@media (max-width: 1024px) { ... } /* перекроет предыдущий */
Решение: при mobile-first использовать min-width, идя от малого к большому:
/* Базовые стили — для мобильных */
.card { flex-direction: column; }
/* Планшеты и выше */
@media (min-width: 768px) {
.card { flex-direction: row; }
}
/* Десктопы */
@media (min-width: 1200px) {
.card { padding: 2rem; }
}
5. Жёсткая привязка к DPR (@media (-webkit-device-pixel-ratio: 2))
Плотность пикселей не коррелирует с размером экрана и быстро устаревает.
Решение: использовать image-set() в CSS или srcset в HTML — браузер сам выберет подходящий ресурс.