В веб-дизайне часто используется прием с плавающими декоративными элементами: вертикальными линиями, статусными бейджами, кнопками шеринга или логотипами, зафиксированными у края экрана. Сложность возникает, когда при прокрутке страницы эти плавающие элементы начинают накладываться на основной контент — заголовки, карточки товаров или текстовые абзацы. Некрасивое перекрытие портит визуальную иерархию и ухудшает читаемость.
Исторически фронтенд-разработчики решали эту задачу с помощью JavaScript. В обработчиках событий скролла вызывались методы getBoundingClientRect() или настраивались наблюдатели через API IntersectionObserver. Однако такой подход создавал постоянную нагрузку на главный поток браузера (Main Thread), приводил к микрофризам анимаций и требовал написания императивного кода для чисто презентационной задачи.
Разработчик Ахмад Шадид представил элегантное решение: детектировать факт приближения или столкновения элементов исключительно средствами декларативного CSS без использования JavaScript.
Архитектурная идея: измерение расстояния и провокация скролла
Предложенный метод объединяет возможности двух современных спецификаций W3C: позиционирования по якорям (CSS Anchor Positioning) и анимаций, управляемых прокруткой (Scroll-driven Animations).
Логика работы строится на трех связанных шагах:
- Динамический зазор между элементами. С помощью якорного позиционирования между декоративным элементом и контентным блоком создается невидимый измерительный слой. Его ширина физически равна расстоянию между объектами на экране.
- Провокация переполнения (Overflow). Внутрь измерителя помещается фиксированный маркер — например, шириной 20 пикселей. Пока расстояние между объектами больше 20 пикселей, элемент отображается свободно. Но как только дистанция сокращается, внутри измерителя возникает горизонтальный скролл.
- Реакция на прокрутку через таймлайн. Сам факт появления прокрутки активирует анимацию, которая через контейнерные запросы стилей (Style Container Queries) плавно скрывает декоративный элемент.
Базовое связывание через Anchor Positioning
На первом этапе плавающий элемент и текстовый блок регистрируются как якоря:
/* 1. Регистрация именованных якорей для плавающего бейджа и контента */
.floating-badge {
position: fixed;
top: 120px;
left: 24px;
anchor-name: --badge;
transition: opacity 0.25s ease, transform 0.25s ease;
}
.content-section {
anchor-name: --content;
max-width: 800px;
margin: 0 auto;
}
Полноценный конвейер детекции столкновения
Теперь между ними натягивается измерительный блок .collision-meter. Его левый край привязан к бейджу, а правый — к секции контента. Свойство timeline-scope поднимает видимость таймлайна прокрутки на уровень родительского контейнера, что позволяет передавать состояние другому элементу на странице:
/* Подъем контекста анимации прокрутки на корневой уровень */
body {
timeline-scope: --badge-collision;
}
/* 2. Измерительный элемент между якорями */
.collision-meter {
position: absolute;
left: anchor(--badge right);
right: anchor(--content left);
top: anchor(--badge top);
bottom: anchor(--badge bottom);
overflow-x: auto;
scroll-timeline: --badge-collision x;
visibility: hidden; /* Скрыт от глаз, но участвует в расчете раскладки */
}
/* Внутренний распорный блок: задает минимально допустимый зазор в 20px */
.collision-meter::after {
content: "";
display: block;
width: 20px;
height: 100%;
}
/* 3. Ключевые кадры: при смещении скролла выставляем флаг столкновения */
@keyframes mark-collision {
from, to {
--is-colliding: 1;
}
}
/* 4. Контейнерный запрос: скрываем плавающий бейдж при опасном сближении */
@container style(--is-colliding: 1) {
.floating-badge {
opacity: 0;
transform: translateX(-16px);
pointer-events: none;
}
}
Практические преимущества и поддержка в браузерах
Главное достоинство чистого CSS-подхода — аппаратное ускорение. Все расчеты координат и анимаций выполняются непосредственно в потоке композитинга (Compositor Thread). Интерфейс сохраняет стабильные 60 или 120 кадров в секунду даже при быстром изменении масштаба окна или резкой прокрутке на мобильных устройствах.
В браузерах без поддержки свойств Anchor Positioning декоративный элемент ведет себя по принципу прогрессивного улучшения (Progressive Enhancement): он остается на экране в стандартном положении без поломки верстки.
