Descripción general
Las sugerencias visuales, como las sombras o los gradientes, ayudan a los usuarios a comprender que pueden desplazarse para ver más contenido. En esta guía, se muestra cómo crear estas sugerencias con la función container-scroll-state-queries de CSS, que permite aplicar diseño a los elementos según el estado de desplazamiento de su contenedor sin depender de objetos de escucha o de observación de desplazamiento de JavaScript.
Implementación
1. Establece el contenedor de desplazamiento
El contenedor de desplazamiento se debe declarar como un contenedor de consulta de estado de desplazamiento.
.scroller {
overflow-y: auto;
/* Establish this element as a scroll-state query container */
container-type: scroll-state;
position: relative;
}
2. Cómo aplicar diseño a los indicadores
Coloca los elementos indicadores (como sombras, gradientes o flechas) dentro del contenedor y dales estilo. De forma predeterminada, no deberían ser visibles. Cuando se muestren, no deben ser interactivos, lo que se logra configurando pointer-events: none.
.indicator-top, .indicator-bottom {
position: sticky;
left: 0;
right: 0;
height: 20px;
opacity: 0;
transition: opacity 0.2s;
pointer-events: none; /* Let clicks pass through */
}
.indicator-top {
top: 0;
background: linear-gradient(to bottom, rgba(0,0,0,0.2), transparent); /* Example: Shadow */
}
.indicator-bottom {
bottom: 0;
background: linear-gradient(to top, rgba(0,0,0,0.2), transparent); /* Example: Shadow */
}
3. Consulta el estado de desplazamiento
Usa la regla @container con la función scroll-state. Verifica si el contenedor se puede desplazar hacia arriba o hacia abajo para mostrar el indicador correspondiente.
/* Show top indicator when the user can scroll up */
@container scroll-state(scrollable: top) {
.indicator-top {
opacity: 1;
}
}
/* Show bottom indicator when the user can scroll down */
@container scroll-state(scrollable: bottom) {
.indicator-bottom {
opacity: 1;
}
}
Estrategias de resguardo
Resguardo básico
Si no se admite la función, los indicadores permanecerán invisibles. Como se trata de sugerencias y no son fundamentales para la funcionalidad, es aceptable omitirlas en los navegadores no compatibles.
Resguardo avanzado (Intersection Observer)
Si se requieren las sugerencias, usa un IntersectionObserver para activar o desactivar las clases cuando los elementos centinela en la parte superior e inferior del desplazador entren y salgan del puerto de desplazamiento.
<!-- Sentinel elements placed at the ends of the scroller -->
<div class="sentinel-top"></div>
<!-- Content goes here -->
<div class="sentinel-bottom"></div>
/* Marker styling to ensure it does not affect layout */
.sentinel-top, .sentinel-bottom {
height: 0;
width: 0;
visibility: hidden;
}
.scroller.scrolled-down .indicator-top {
opacity: 1;
}
.scroller.can-scroll-down .indicator-bottom {
opacity: 1;
}
if (!CSS.supports('container-type', 'scroll-state')) {
const topSentinel = document.querySelector('.sentinel-top');
const bottomSentinel = document.querySelector('.sentinel-bottom');
const scroller = document.querySelector('.scroller');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.target === topSentinel) {
// If top sentinel is not intersecting, we have scrolled down
scroller.classList.toggle('scrolled-down', !entry.isIntersecting);
}
if (entry.target === bottomSentinel) {
// If bottom sentinel is intersecting, we reached the bottom
scroller.classList.toggle('can-scroll-down', !entry.isIntersecting);
}
});
}, { root: scroller });
observer.observe(topSentinel);
observer.observe(bottomSentinel);
}