Smooth Scroll es cuando viajamos dentro del mismo documento deslizando de una manera delicada de un lado a otro.
Cuando hay enlaces dentro de nuestra página, el comportamiento natural al tocarlo es que se accione la liga y se salte repentinamente a donde el enlace está direccionado, el smooth scroll tiene como objetivo que ese movimiento sea más cómodo, hace un deslizamiento vertical hacia el lugar establecido en vez de saltar.
Existen varias formas de lograrlo, en este artículo lo haremos con css, javascript y jQuery
Lo primero que hay que saber es que el movimiento dentro de una misma página se logra con un ancla apuntando a un identidad:
<a href="#identidad">enlace</a>
<section>
<p>lorem ipsum dolor sit amet</p>
<p>lorem ipsum dolor sit amet</p>
</section>
<section id="identidad">
<p>lorem ipsum dolor sit amet</p>
<p>lorem ipsum dolor sit amet</p>
</section>
Así se ve el desplazamiento saltando entre #target sin smooth scroll.
Ver ejemploCSS
La forma más sencilla y próxima es la propiedad de css scroll-behavior: auto | smooth; (Ver estandarización) con las desventajas que implica utilizar las novedades de las estandarizaciones.
Hasta el día de hoy el sitio “Can I use” le otorga un 75% de compatibilidad de navegador dejando por fuera Safari, ios Safari, Opera mini y IE o Edge (Antes de la nueva versión con Chromium de IE). Tal circunstancia puede que no apetezca a unos cuantos pero siendo claros es el futuro y vale la pena que lo veamos, además es la forma más sencilla.
Acá el truco que es muy sencillo:
html {
scroll-behavior: smooth;
}
Funciona de esta manera:
Ver ejemploVanilla javascript
Siempre se puede recurrir a las librerías de javascript y más adelante lo haremos con jQuery, pero también es posible con javascript solo.
// Scroll a un valor específico
// scrollTo es lo mismo
window.scroll({
top: 2500,
left: 0,
behavior: 'smooth'
});
// Scroll se mueve cantidad determinada de px desde la posición actual
window.scrollBy({
top: 100, // Puede ser un valor negativo
left: 0,
behavior: 'smooth'
});
// Scroll a cierto elemento
document.querySelector('#uno').scrollIntoView({
behavior: 'smooth'
});
En particular para este ejercicio, voy a utilizar los métodos querySelector() y scrollIntoView, porque a pesar de que se puede planear con los demás métodos, estableciendo una distancia en pixeles, se tiene que ser muy preciso, mientras que la forma seleccionada se viaja a un selector. Una aclaración pertinente es que este método presenta problemas con navegadores móviles…
Para poder activarlo, lo haremos con una función, que llamaremos saturno, por la obvia razón de que nos va a llevar a la imagen del planeta saturno:
function saturno() {
document.querySelector('#uno').scrollIntoView({ behavior: 'smooth' });
}
Para activar la función que nos va a llevar a saturno en el enlace utilizaremos el evento de html onclick.
<a href="javascript:void(0);" onclick="saturno();">Uno</a>
El void de javascript lo utilizaremos para evitar que funcione el href como tal y que no haga movientos a una id vacía como cuando ponemos un href=”#”. Como sería lógico suponer las funciones serían tres al igual que los enlaces, acá el código completo de html y javascript:
HTML
<nav>
<a href="javascript:void(0);" onclick="saturno();">Uno</a>
<a href="javascript:void(0);" onclick="tierra();">Dos</a>
<a href="javascript:void(0);" onclick="astronauta();">Tres</a>
</nav>
<article id="uno">
<img src="./img/saturn.png">
</article>
<article id="dos">
<img src="./img/earth.png">
</article>
<article id="tres">
<img src="./img/astronauta.png">
</article>
Javascript
function saturno() {
document.querySelector('#uno').scrollIntoView({ behavior: 'smooth' });
}
function tierra() {
document.querySelector('#dos').scrollIntoView({ behavior: 'smooth' });
}
function astronauta() {
document.querySelector('#tres').scrollIntoView({ behavior: 'smooth' });
}
Algo importante por resaltar es que cada enlace tendría que tener su propia función, lo que ciertamente lo hace ineficiente si necesitas muchos enlaces o algo más automatizado. Pero veamos el resultado:
Ver ejemploLa opción con jQuery
Lo primero es instalar la librería de jQuery que va a hacer funcionar todo lo siguiente…
// Selecciona todos los enlaces con símbolo de número (identidades).
$('a[href*="#"]')
// Remueve los enlaces que no hacen nada
.not('[href="#"]')
.not('[href="#0"]')
.click(function(event) {
// Transforma los enlaces en la página al hostname
if (
location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '')
&&
location.hostname == this.hostname
) {
// Establece a qué elemento se va a mover
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
// Establece la existencia del target.
if (target.length) {
// Previene el comportamiento por defecto del enlace, sólo si la animación se va a llevar a cabo.
event.preventDefault();
$('html, body').animate({
scrollTop: target.offset().top
}, 1000, function() { // 1000 representa el tiempo de la animación... 1 segundo
// Llamada después de la animación
// Establece el focus
var $target = $(target);
$target.focus();
if ($target.is(":focus")) { // Revisa si se logró el focus
return false;
} else {
$target.attr('tabindex','-1'); // Agrega z-index a los elementos que no pueden tener focus
$target.focus(); // Establece el focus de nuevo
};
});
}
}
});
Los comentarios son guías de qué hace cada parte del bloque de código… Pero lo importante de esto es que hace referencia a cada enlace que tenga una identidad por lo cual es muy útil cuando quieres automatizar a mayor nivel el desempeño de tu sitio. Veamos el resultado:
Ver ejemploEspero sea útil este recuento, si tienen alguna duda o un aporte, por favor dejen un comentario… Enjoy!