Обзор
Чтобы плавающие кнопки, например "Наверх", не мешали пользователям, показывайте их только тогда, когда они нужны. В этом руководстве показано, как создать такие элементы с помощью CSS container-scroll-state-queries, который позволяет стилизовать элементы на основе положения прокрутки их контейнера, не полагаясь на прослушиватели или наблюдатели прокрутки JavaScript.
Реализация
1. Создайте контейнер прокрутки
Контейнер прокрутки должен быть объявлен как контейнер запросов состояния прокрутки.
.scroller {
overflow-y: auto;
/* Establish this element as a scroll-state query container */
container-type: scroll-state;
}
2. Как настроить стиль плавающего элемента
Поместите элемент в контейнер и настройте его стиль. По умолчанию он должен быть скрыт.
.back-to-top {
position: sticky;
bottom: 20px;
visibility: hidden;
opacity: 0;
translate: 0 20px;
transition:
visibility 0.3s,
opacity 0.3s ease,
translate 0.3s ease;
}
3. Реагирование на состояние прокрутки
Используйте правило @container с функцией scroll-state. Чтобы проверить, прокрутил ли пользователь страницу вниз, проверьте, можно ли прокрутить контейнер вверх.
/* When the container can be scrolled toward the top, it means the user has scrolled down */
@container scroll-state(scrollable: top) {
.back-to-top {
visibility: visible;
opacity: 1;
translate: 0 0;
}
}
Резервные стратегии
Базовое резервное объявление
Если свойство container-scroll-state-queries не поддерживается, плавающий элемент останется невидимым из-за значения visibility: hidden по умолчанию. Чтобы обеспечить работоспособность, вы можете сделать элемент всегда видимым в неподдерживаемых браузерах.
/* Fallback for browsers that do not support the feature */
.back-to-top {
visibility: visible; /* Always visible */
opacity: 1;
}
/* Override for supported browsers to handle dynamic visibility */
@supports (container-type: scroll-state) {
.back-to-top {
visibility: hidden;
opacity: 0;
}
@container scroll-state(scrollable: top) {
.back-to-top {
visibility: visible;
opacity: 1;
translate: 0 0;
}
}
}
Расширенное резервное решение (Intersection Observer)
Если требуется динамическая видимость, используйте IntersectionObserver, чтобы переключать класс, когда контрольный элемент в верхней части прокручиваемой области выходит из поля зрения.
<!-- Sentinel element placed at the top of the scroller -->
<div class="scroll-sentinel"></div>
/* Marker styling to ensure it does not affect layout */
.scroll-sentinel {
height: 0;
width: 0;
visibility: hidden;
}
.scrolled .back-to-top {
visibility: visible;
opacity: 1;
translate: 0 0;
}
if (!CSS.supports('container-type', 'scroll-state')) {
const sentinel = document.querySelector('.scroll-sentinel');
const scroller = document.querySelector('.scroller');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
// If the sentinel is NOT intersecting, it means the user has scrolled down
if (!entry.isIntersecting) {
scroller.classList.add('scrolled');
} else {
scroller.classList.remove('scrolled');
}
});
}, { root: scroller });
observer.observe(sentinel);
}