Back

Предотвращение смещения макета с помощью современного CSS

Предотвращение смещения макета с помощью современного CSS

Неожиданные скачки контента раздражают пользователей и ухудшают показатели Core Web Vitals. Cumulative Layout Shift (CLS) измеряет эти резкие перемещения — не только во время начальной загрузки, но и на протяжении всей сессии страницы. Кнопка, на которую вы собираетесь нажать, внезапно перемещается. Текст переформатируется при смене шрифтов. Встроенный элемент сдвигает контент вниз во время прокрутки.

Современный CSS предоставляет точные инструменты для предотвращения смещения макета до того, как оно произойдёт. В этой статье рассматриваются CSS-ориентированные техники, которые работают в продакшене сегодня, с акцентом на внутренние размеры, стабильность шрифтов и паттерны анимации, которые удерживают ваш показатель CLS ниже порога 0.1.

Ключевые выводы

  • CLS накапливается на протяжении всего жизненного цикла страницы, а не только во время начальной загрузки — мониторинг реальных пользователей часто показывает более высокие значения, чем лабораторные инструменты
  • Объявляйте внутренние размеры с помощью aspect-ratio, атрибутов width и height, чтобы зарезервировать пространство до прибытия контента
  • Используйте size-adjust и свойства переопределения метрик в объявлениях @font-face для устранения переформатирования при смене шрифтов
  • Анимируйте только свойства transform и opacity, чтобы избежать пересчёта макета

Почему CLS выходит за рамки загрузки страницы

CLS накапливается на протяжении всего жизненного цикла страницы. Лабораторные инструменты, такие как Lighthouse, фиксируют смещения во время загрузки, но мониторинг реальных пользователей (RUM) часто выявляет более высокие показатели. В чём разница? В смещениях после загрузки из-за ленивого контента, поздно внедряемой рекламы или переходов, превышающих льготный период в 500 миллисекунд после взаимодействия с пользователем.

Смещения, происходящие в течение 500 мс после квалифицируемого пользовательского ввода, не учитываются в CLS — они ожидаемы. Всё остальное учитывается. Это означает, что ленивая загрузка при прокрутке, состояния при наведении, изменяющие размер элементов, и клиентские переходы между маршрутами — всё это вносит вклад, если вызывает неожиданное перемещение.

Резервирование пространства с помощью внутренних размеров

Основа предотвращения смещения макета — объявление размеров до прибытия контента. Современный CSS делает это простым.

Изображения и медиа

Свойство aspect-ratio позволяет браузерам резервировать пространство, используя только соотношение сторон, без фиксированных значений в пикселях. В сочетании с атрибутами width и height на элементах <img> браузеры вычисляют зарезервированное пространство сразу во время парсинга HTML.

Для адаптивных изображений устанавливайте размеры на элементах <source> внутри <picture>, чтобы обрабатывать художественное направление без смещений. Браузер использует эти значения для установки соотношений сторон до загрузки любых данных изображения.

Встроенные элементы и динамический контент

Сторонние встроенные элементы — видео, карты, посты из социальных сетей — редко сообщают свои окончательные размеры. Используйте min-height или aspect-ratio на элементах-контейнерах, чтобы зарезервировать ожидаемое пространство. Когда точные размеры неизвестны, резервируйте пространство для наиболее распространённого размера на основе вашей аналитики, принимая незначительные смещения для выбросов.

Для контента, внедряемого через JavaScript, применяется тот же принцип: контейнеры должны иметь внутренний размер, объявленный в CSS, до выполнения скриптов.

Загрузка шрифтов без переформатирования

Веб-шрифты вызывают смещения, когда запасные и финальные шрифты имеют разные метрики. Одного свойства font-display недостаточно — swap всё равно вызывает переформатирование при различии метрик.

Метрически выровненные запасные шрифты

Современный CSS предлагает size-adjust, ascent-override, descent-override и line-gap-override внутри объявлений @font-face. Эти свойства настраивают метрики вашего запасного шрифта в соответствии с веб-шрифтом, устраняя видимое переформатирование даже при смене.

Сочетайте это с font-display: optional для самого строгого предотвращения CLS — веб-шрифт отображается только если он доступен во время начального макета. Для менее агрессивных подходов переопределение метрик с font-display: swap обеспечивает читаемый текст немедленно, минимизируя величину смещения.

Предварительная загрузка критических шрифтов с помощью <link rel="preload"> увеличивает вероятность их доступности для первой отрисовки, сокращая окно отображения запасных шрифтов.

Анимации и расширение UI

Анимация width, height, top, left или margin запускает пересчёт макета и вносит вклад в CLS. Анимация transform и opacity этого не делает — эти свойства выполняются на композиторе без влияния на поток документа.

Безопасные паттерны анимации

Масштабируйте элементы с помощью transform: scale(), а не изменения размеров. Перемещайте элементы с помощью transform: translate() вместо позиционных свойств. Эти подходы создают визуальное движение без смещения окружающего контента.

Для расширяющегося UI — аккордеонов, выпадающих списков, подсказок — смещение приемлемо, когда оно следует за взаимодействием пользователя в течение 500 мс. Если расширение происходит автоматически или после задержки, резервируйте максимальное расширенное пространство заранее или позиционируйте расширяющийся элемент вне потока документа, используя position: absolute или паттерны оверлеев.

Переходы при смене маршрутов

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

Валидация вашего подхода

Панель Performance в Chrome DevTools показывает отдельные смещения макета с их показателями и затронутыми элементами. Трек Layout Shifts визуализирует кластеры смещений, помогая выявить паттерны.

Для мониторинга в продакшене RUM-решения, использующие библиотеку web-vitals, фиксируют реальный пользовательский CLS с атрибуцией элементов. Сравнивайте полевые данные с лабораторными измерениями — расхождения указывают на смещения после загрузки, которые пропускают ваши синтетические тесты.

Заключение

Предотвращение смещения макета сводится к одному принципу: объявляйте внутренний размер для всего до его отрисовки. Используйте aspect-ratio для медиа, переопределение метрик для шрифтов и transform для анимаций. Резервируйте пространство для контента с поздней загрузкой и проверяйте как лабораторными инструментами, так и полевыми данными.

Современный CSS для предотвращения CLS — это не трюки, а предоставление браузерам информации, необходимой для правильного выделения пространства с самого начала.

Часто задаваемые вопросы

Google считает показатель CLS ниже 0.1 хорошим, между 0.1 и 0.25 — требующим улучшения, а выше 0.25 — плохим. Стремитесь удерживать показатель ниже 0.1 для оптимального пользовательского опыта и производительности Core Web Vitals. Отслеживайте как лабораторные, так и полевые данные, поскольку показатели реальных пользователей часто отличаются от синтетических тестов.

Lighthouse измеряет CLS только во время загрузки страницы в контролируемых условиях. Мониторинг реальных пользователей фиксирует смещения на протяжении всей сессии, включая ленивую загрузку контента, поздно внедряемую рекламу и взаимодействия пользователей. Смещения после загрузки, происходящие после завершения измерения Lighthouse, появятся только в полевых данных.

Нет, одного font-display swap недостаточно для предотвращения смещения макета. Оно обеспечивает видимость текста во время загрузки шрифта, но всё равно вызывает переформатирование, когда веб-шрифт заменяет запасной. Чтобы предотвратить смещение, комбинируйте его со свойствами переопределения метрик, такими как size-adjust, ascent-override и descent-override, для соответствия метрик запасного и веб-шрифта.

Нет. Анимации, использующие свойства transform и opacity, выполняются в потоке композитора и не влияют на поток документа, поэтому не вызывают смещение макета. Только анимации, изменяющие свойства, влияющие на макет, такие как width, height, margin или позиционные значения, запускают пересчёт и вносят вклад в CLS.

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..

OpenReplay