Ajuste de desplazamiento de CSS práctico | Programar Plus

El ajuste de desplazamiento de CSS le permite bloquear la ventana gráfica en ciertos elementos o ubicaciones después de que un usuario haya terminado de desplazarse. Es genial para crear interacciones como esta:

Demo en vivo

Soporte de navegador y uso básico

La compatibilidad del navegador con el ajuste de desplazamiento de CSS ha mejorado significativamente desde que se introdujo en 2016, con Google Chrome (69+), Firefox, Edge y Safari, todos compatibles con alguna versión del mismo.

Estos datos de soporte del navegador son de Caniuse, que tiene más detalles. Un número indica que el navegador admite la función en esa versión en adelante.

Escritorio

Cromo Firefox ES DECIR Borde Safari
69 68 11 * 79 11

Móvil / Tableta

Android Chrome Android Firefox Androide Safari de iOS
96 95 96 11.0-11.2

El ajuste de desplazamiento se utiliza configurando el scroll-snap-type propiedad en un elemento contenedor y la scroll-snap-align propiedad sobre los elementos dentro de ella. Cuando se desplaza el elemento contenedor, se ajustará a los elementos secundarios que haya definido. En su forma más básica, se ve así:

<div class="container">
  <section class="child"></section>
  <section class="child"></section>
  <section class="child"></section>
  <p>...</p>
</div>
.container {
  scroll-snap-type: y mandatory;
}

.child {
  scroll-snap-align: start;
}

Esto es diferente a la primera versión de la especificación, que le permitía establecer puntos de ajuste manualmente usando el repeat palabra clave:

.container {
  /* OLD */
  scroll-snap-points-y: repeat(300px);
}

Este método es bastante limitado. Dado que solo permite puntos de ajuste espaciados uniformemente, realmente no puede crear una interfaz que se ajuste a elementos de diferentes tamaños. Si los elementos cambian su forma en diferentes tamaños de pantalla, también es probable que tenga problemas.

En el momento de escribir este artículo, Firefox, Internet Explorer y Edge admiten la versión anterior de la especificación, mientras que Chrome (69+) y Safari admiten el método más nuevo basado en elementos.

Puede usar ambos métodos uno junto al otro (si su diseño lo permite) para admitir ambos grupos de navegadores:

.container {
  scroll-snap-type: mandatory;
  scroll-snap-points-y: repeat(300px);
  scroll-snap-type: y mandatory;
}

.child {
  scroll-snap-align: start;
}

Yo diría que una opción más flexible es usar la sintaxis basada en elementos exclusivamente y cargar un polyfill para admitir navegadores que aún no lo admiten. Este es el método que estoy usando en los ejemplos siguientes.

Desafortunadamente, el polyfill no viene con un paquete de navegador, por lo que es un poco complicado de usar si no está utilizando un proceso de compilación. La forma más fácil de evitar esto que he encontrado es vincular al script en bundle.run e inicializarlo usando cssScrollSnapPolyfill() una vez que se carga el DOM. También vale la pena señalar que este polyfill solo admite la sintaxis basada en elementos, no la repeat-método.

Propiedades del contenedor principal

Al igual que con cualquier propiedad, es una buena idea familiarizarse con los valores que aceptan. Las propiedades de ajuste de desplazamiento se aplican a los elementos principales y secundarios, con valores específicos para cada uno. De la misma manera que lo hacen flexbox y grid, donde el padre se convierte en un contenedor “flexible” o “grid”. En este caso, el padre se convierte en un contenedor instantáneo, por así decirlo.

A continuación, se muestran las propiedades y los valores del contenedor principal y cómo funcionan.

scroll-snap-type “obligatorio” frente a “proximidad”

El mandatory valor significa que el navegador tiene que ajustarse a un punto de ajuste cada vez que el usuario deja de desplazarse. El proximity La propiedad es menos estricta, lo que significa que el navegador puede ajustarse a un punto de ajuste si lo considera apropiado. En mi experiencia, esto tiende a activarse cuando dejas de desplazarte dentro de unos cientos de píxeles de un punto de ajuste.

En mi propio trabajo, encontré que mandatory hace que la experiencia del usuario sea más consistente, pero también puede ser peligrosa, como señala la especificación. Imagine un escenario en el que un elemento dentro de un contenedor de desplazamiento es más alto que la ventana gráfica:

Si ese contenedor está configurado para scroll-snap-type: mandatory, siempre se colocará en la parte superior del elemento o en la parte superior del que está debajo, haciendo que la parte media del elemento alto sea imposible de desplazarse.

relleno de desplazamiento

De forma predeterminada, el contenido se ajustará a los bordes del contenedor. Puede cambiar eso configurando el scroll-padding propiedad en el contenedor. Sigue la misma sintaxis que la normal. padding propiedad.

Esto puede ser útil si su diseño tiene elementos que podrían interferir con el contenido, como un encabezado fijo.

Propiedades de los niños

Ahora pasemos a las propiedades de los elementos secundarios.

scroll-snap-align

Esto le permite especificar qué parte del elemento se supone que debe ajustarse al contenedor. Tiene tres valores posibles: start, center, y end.

Estos son relativos a la dirección de desplazamiento. Si se desplaza verticalmente, start se refiere al borde superior del elemento. Si se desplaza horizontalmente, se refiere al borde izquierdo. center y end seguir el mismo principio. Puede establecer un valor diferente para cada dirección de desplazamiento separados por un espacio.

scroll-snap-stop “normal” frente a “siempre”

De forma predeterminada, el ajuste de desplazamiento solo se activa cuando el usuario deja de desplazarse, lo que significa que puede omitir varios puntos de ajuste antes de detenerse.

Puede cambiar esto configurando scroll-snap-stop: always en cualquier elemento hijo. Esto obliga al contenedor de desplazamiento a detenerse en ese elemento antes de que el usuario pueda continuar desplazándose.

En el momento de escribir este artículo, ningún navegador admite scroll-snap-stop de forma nativa, aunque hay un error de seguimiento para Chrome.

Veamos algunos ejemplos de uso del ajuste de desplazamiento.

Ejemplo 1: lista vertical

Para hacer que una lista vertical se ajuste a cada elemento de la lista, solo se necesitan unas pocas líneas de CSS. Primero, le decimos al contenedor que se ajuste a lo largo de su eje vertical:

.container {
  scroll-snap-type: y mandatory;
}

Luego, definimos los puntos de ajuste. Aquí, estamos especificando que el cima de cada elemento de la lista será un punto de ajuste:

.child {
  scroll-snap-align: start;
}

Ejemplo 2: control deslizante horizontal

Para hacer un control deslizante horizontal, le decimos al contenedor que se ajuste a lo largo de su eje x. También estamos usando scroll-padding para asegurarse de que los elementos secundarios se ajusten al centro del contenedor.

.container {
  scroll-snap-type: x mandatory;
  scroll-padding: 50%;
}

Luego, le decimos al contenedor a qué puntos se debe ajustar. Para centrar la galería, definimos el punto central de cada elemento como un punto de ajuste.

.child {
  scroll-snap-align: center;
}

Ejemplo 3: pantalla completa vertical

Podemos establecer los puntos de ajuste directamente en el elemento:

html { /* body won't work ¯_(ツ)_/¯ */
  scroll-snap-type: y mandatory;
}

/* Although I'm told that html doesn't work in Safari 
   and body does, so maybe use both? */

Luego, hacemos que cada sección tenga el tamaño de la ventana gráfica y definimos el borde superior como un punto de ajuste:

section {
  height: 100vh;
  width: 100vw;
  scroll-snap-align: start;
}

Ejemplo 4: pantalla completa horizontal

Este es el mismo tipo de concepto que la versión vertical, pero con el punto de ajuste en el eje x en su lugar.

body {
  scroll-snap-type: x mandatory;
}

section {
  height: 100vh;
  width: 100vw;
  scroll-snap-align: start;
}

Ejemplo 5: cuadrícula de imágenes 2D

El ajuste de desplazamiento puede funcionar en dos direcciones al mismo tiempo. De nuevo, podemos configurar scroll-snap-type directamente en el elemento:

.container {
  scroll-snap-type: both mandatory;
}

Luego, definimos la esquina superior izquierda de cada mosaico como un punto de ajuste:

.tile {
  scroll-snap-align: start;
}

Algunas reflexiones sobre la experiencia del usuario

Jugar con el desplazamiento es un negocio arriesgado. Dado que es una parte fundamental de la interacción con la web, cambiarlo de cualquier manera puede resultar discordante: el término scrolljacking que se usa para describir ese tipo de experiencia.

Lo mejor del ajuste de desplazamiento basado en CSS es que no está tomando control directo sobre la posición de desplazamiento. En cambio, solo le está dando al navegador una lista de posiciones para ajustar de una manera que sea apropiada para la plataforma, el método de entrada y las preferencias del usuario. Esto significa que una interfaz de desplazamiento que construya se sentirá como la interfaz nativa (es decir, usando las mismas animaciones, etc.) en cualquier plataforma en la que se vea.

Para mí, esta es la ventaja clave del ajuste de desplazamiento de CSS sobre las bibliotecas de JavaScript que ofrecen una funcionalidad similar.

Esto funciona bastante bien en mi experiencia, especialmente en dispositivos móviles. Quizás esto se deba a que el ajuste de desplazamiento ya es parte de la interfaz de usuario nativa en plataformas móviles. (Imagine las pantallas de inicio en iOS y Android; son esencialmente controles deslizantes horizontales con puntos de ajuste). La interacción en Chrome en Android es particularmente agradable porque se siente como un desplazamiento regular, pero la ventana gráfica siempre se detiene en un instante. punto:

Definitivamente hay algunas matemáticas sofisticadas para hacer que esto suceda. Gracias al ajuste de desplazamiento de CSS, lo obtenemos de forma gratuita.

Por supuesto, no deberíamos empezar a lanzar puntos de ajuste a todo. Cosas como las páginas de artículos funcionan bien sin ellas. Pero creo que pueden ser una buena mejora en la situación correcta: las galerías de imágenes y las presentaciones de diapositivas parecen buenos candidatos, pero tal vez haya potencial más allá de eso.

Conclusión

Si se hace con cuidado, el ajuste de desplazamiento puede ser una herramienta de diseño útil. Los puntos de ajuste CSS le permiten conectarse a la interacción de desplazamiento nativa del navegador, por lo que su interfaz se siente perfecta y fluida. Con una API de JavaScript potencialmente en el horizonte, estos se volverán aún más poderosos. Aún así, un toque ligero es probablemente el camino a seguir.