soy Kseso y esto EsCSS

Cómo evitar el salto lateral del contenido al aparecer el scroll vertical

Sencilla técnica Css para evitar el pequeño salto lateral del contenido centrado al aparecer la barra lateral de scroll después de cargada la página o al pasar entre páginas distintas

Cómo evitar el salto lateral del contenido al aparecer el scroll vertical

·Por Kseso ✎ 1
Cómo evitar el movimiento lateral entre páginas con y sin scroll vertical

Centrar en la horizontal una página con margin: 0 auto; tiene un pequeño efecto poco grato en una circustancia: en algunos navegadores fuerza un pequeño salto o desplazamiento lateral del contenido a la izquierda al aparecer la barra de scroll vertical.

Esto ocurre tanto al navegar entre páginas (al pasar de una página "corta" sin scroll a otra que sí lo tenga) o en la misma página si el scroll-Y aparece después de cargada y dibujada la página.

Este efecto de salto o desplazamiento horizontal es especialmente molesto si el scroll aparece al realizarse alguna transformación (transform) por ser el salto cíclico o intermitente: "ahora sí ahora no, ahora sí ahora no..."

Tal como puedes ver en el siguiente pen:

See the Pen KwMvgo by Kseso (@Kseso) on CodePen.

La solucción clásica para evitar ese salto es declarar el siguiente css:

html { overflow-y: scroll; }

Esta declaración fuerza la aparición del escroll vertical siempre, no importa que por el contenido del documento sea o no necesario, en cuyo caso aparecerá deshabilitada (grisacea).

Esta solucción no está mal, pero no es la ideal. Se podría mejorar para que la barra de scroll vertical se muestre si y sólo si es necesaria.

La solución para evitar el salto horizontal

La forma que encontré para evitar este desplazamiento horizontal de los contenidos al aparecer el scrool-Y después de estar cargada la página es usar 100vw junto a 100%.

La diferencia entre ambas unidades (vw & %) es pequeña pero sustancial:

  • width: 100vw es la anchura total del espacio de representación del documento (viewport en inglés) o de la ventana del navegador.
  • width: 100% es la anchura total del elemento. Dependiendo del modelo de caja usada (tradicional o variante box-sizing usada) puede incluir o no el padding pero nunca los márgenes.

En el elemento raíz o Html la pequeña diferencia entre ambas anchuras es que en el 100vw la barra de scroll está incluida y en 100% no.

Usando la función Css calc() podemos crear un margen izquierdo en la página de la misma anchura que la anchura del scrollbar cuando éste aparece y que desaparece (no existe tal margen) cuando no hay barra de scroll-Y.

Esto último puesto en código Css queda así:

html { margin-left: calc(100vw - 100%); margin-right: 0; }

Ahora al aplicar este código al mismo caso del pen anterior, fíjate que ocurre en el siguiente. Como puedes observar el salto lateral o desplazamiento a la izquierda de la esfera ha desaparecido. Se mantiene en la misma posición haya o no barra de scroll vertical.

See the Pen LEZjmp by Kseso (@Kseso) on CodePen.

Y esto es así porque mientras no hay scroll-Y el resultado de la resta incluida en la función Css calc(100vw - 100%) es cero y al aparecer el scroll es de un valor igual a la anchura de la barra de desplazamiento.

Esta técnica tiene un pequeño inconveniente: al ser usada en diseños RWD cuando el tamaño de la página (pantalla del dispositivo) es lo suficientemente pequeña pueden ocurrir que el margen izquierdo sea mayor que el derecho y a esas resoluciones hacerse muy evidente (descentrarse).

Si te topas con ello, la solucción pasa por incluir la función en una media query:

@media screen and (min-width: 800px) { html { margin-left: calc(100vw - 100%); margin-right: 0; } }

El valor de la anchura del ejemplo (min-width: 800px) es totalmente arbitrario.

Alcance de la solucción

Este código funciona en IE9+, Chrome y Firefox, pero por desgracia no lo hace en Opera y Safari. Creo que no lo hace en Safari por un bug de Webkit en el manejo de la función calc() si incluye valores relativos al viewport.
Las nuevas versiones de Opera basadas en Chromiun no deberían presentar problemas ya que en Chrome actual funciona.

Créditos y reconocimiento de autoría

Ayke van Laëthem Este artículo está basado, que no traducido, en el post original de Ayke van Laëthem Fix 'jumping scrollbar' issue using only CSS en el que presenta y da a conocer esta técnica.
Te recomiendo consultar el original [ING] como agradecimiento a su aportación y así de paso sabrás exáctamente lo que el autor dice.
No he podido localizarlo en redes sociales.

avatar del Editor del blog

the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso