Todas las Noticias en Películas, Avances de Películas y Reseñas.

Cómo crear una barra de navegación adhesiva [CSS & JS]

Para crear una barra de navegación pegajosa, usa la posición: fija; Propiedad CSS para “pegar” su barra de navegación a la ventana gráfica y posición: pegajosa; para que se adhiera a su elemento padre.

En esta publicación, aprenderá lo que significa todo esto y cómo hacer una barra de navegación pegajosa para su propio sitio.

¡Vamos!

¿Qué es una barra de navegación fija?

Pero antes de continuar, debemos aclarar una cosa. ¿A qué te refieres exactamente con “pegajoso”?

Verá, en el mundo de CSS, pegajoso significa algo muy específico. De hecho, hay dos configuraciones que usas para “pegar” un elemento a cierta parte de la pantalla mientras el visitante se desplaza. Estos son:

position: sticky;

o …

position: fixed;

Hay una gran diferencia entre ellos:

  • los elementos fijos permanecen en la misma posición en la ventana gráfica, independientemente del desplazamiento. Entonces, a medida que se desplaza hacia abajo en la página, parece que ‘flotan’ sobre el contenido.
  • Los elementos adhesivos son similares: permanecen en la misma posición en la ventana gráfica, independientemente del desplazamiento, pero solo dentro de su elemento principal. Cuando la ventana gráfica llega al final del padre de un elemento fijo, se comportará como un elemento relativamente posicionado.

En esta publicación, aprenderá cómo hacer una versión de uso común de la barra de navegación fija. – uno que comienza posicionado en el encabezado de su sitio, pero no justo en la parte superior. Entonces, a medida que el visitante se desplaza, se “pega” a la parte superior de la pantallay permanece a la vista mientras se desplazan.

Así es como lo haces…

1) Cree un sitio web simple para Sticky Navbar

Primero, construyamos un sitio para que entre la barra de navegación fija. Haremos un sitio simple de una página con algunos chistes de comediantes famosos.

Cada enlace en nuestra barra de navegación fija apuntará a una sección diferente del sitio, por lo que usaremos algunos elementos

, con algo de espacio para el contenido dentro. Aquí está la estructura:

<section id="">
<article>
<h2></h2>
<p></p>
</article>
</section>

Y aquí está el CSS:

@import url('https://fonts.googleapis.com/css2?family=Caveat&family=Poppins:wght@300&display=swap');

body {
font-family: poppins, sans-serif;
margin: 0px;
}

section {
min-height: 100vh;
}

article {
width: 90%;
max-width: 600px;
padding: 20px;
margin: 0px auto;
}

h2 {
text-align: center;
padding: 40px 0px 0px 0px;
font-size: 3em;
}

p {
font-size: 1.5em;
text-align: center;
}

Luego podemos diseñar cada sección individual a través de su id, por lo que la sección del comediante Bill Hicks podría verse así:

section#bill-hicks {
background: rgb(123,211,232);
background: linear-gradient(135deg, rgba(123,211,232,1) 0%, rgba(232,123,165,1) 0%, rgba(255,50,50,1) 100%);
color: #40081a;
}

Y después de buscar en Google algunos chistes y agregar algunos estilos más para cada sección, obtenemos esto:

ver la pluma
en
CódigoPen.

2) Construya la barra de navegación

Ahora, para agregar la barra de navegación, que colocaremos debajo de la sección #header en el marcado. Primero el HTML:

<section id="header">
<article>
<h2>Let's read some jokes!</h2>
</article>
</section>
<nav>
<a href="#header">Home</a>
<a href="#tim-vine">Tim Vine</a>
<a href="#bill-hicks">Bill Hicks</a>
<a href="#stewart-francis">Stewart Francis</a>
</nav>

Luego algo de CSS para que se vea más presentable y para colocarlo en la parte superior de la página:

nav {
background-color: #3a24f0;
padding: 10px;
text-align: center;
width: 100%;


position: sticky;
top: 0px;
}

nav a {
color: white;
text-decoration: none;
margin: 0px 10px;
}

nav a:hover {
text-decoration: underline;
}

@media
(prefers-reduced-motion: no-preference) {
html {
scroll-behavior: smooth;
}
}

Que resulta así:

ver la pluma
en
CódigoPen.

Cómo esto hace que la barra de navegación sea pegajosa

Entonces, ¿cómo funciona esto?

Bueno, como recordará, fixed pega un elemento a la ventana gráfica y sticky lo pega a su elemento principal. Pero aquí, nuestra barra de navegación está debajo del encabezado en el marcado, en lugar de ser un elemento secundario. ¡Así que su padre es el cuerpo!

Recomendado:  ¿Cómo transmitir ABC en vivo en línea sin cable?

Le dimos al elemento un valor máximo de 0. Hasta que el elemento alcance esa posición en la ventana gráfica, se comportará como si tuviera una posición: relativa. Una vez que la parte superior del elemento llega a la parte superior de la ventana gráfica, position: sticky se activa y se comporta como si tuviera position: absolute.

Esta es una solución realmente genial y significa que no tiene que usar JS para crear este efecto. Sin embargo, solo funciona cuando el padre de la barra de navegación es. Si eso no es posible en tu caso, ¡no te preocupes! Hay otra manera…

3) Creación de una Sticky Navbar con JS – Posicionamiento inicial

Digamos que, por alguna razón, su barra de navegación tiene que ser un elemento secundario de su #encabezado, pero aún desea que sea fijo.

Tu HTML puede verse así:

<section id="header">
<article>
<h2>Let's read some jokes!</h2>
</article>
<nav id="main-nav">
<a href="#header">Home</a>
<a href="#tim-vine">Tim Vine</a>
<a href="#bill-hicks">Bill Hicks</a>
<a href="#stewart-francis">Stewart Francis</a>
</nav>
</section>

Ahora, el padre de #main-nav es #header, por lo que si usamos position sticky, no permanecerá a la vista después de que nos hayamos desplazado más allá. Por ahora, posicionémoslo relativamente:

#main-nav {
background-color: #1e1e1e;
padding: 10px;
text-align: center;
width: 100%;
position: relative;
box-sizing: border-box;
height: 45px;
}

Por el momento, es solo una barra de navegación estándar…

ver la pluma
en
CódigoPen.

4) Creación de una Sticky Navbar con JS: el efecto Sticky

Debido a que el padre de la barra de navegación no es el cuerpo, en realidad tendremos que usar position: fixed para pegar la barra de navegación en la parte superior de la pantalla.

Pongamos esto en una clase:

#main-nav.sticky {
position: fixed;
top: 0;
}

A continuación, debemos agregar esta clase al elemento #main-nav cuando el usuario se desplaza más allá.

Para saber si el visitante se ha desplazado más allá de la barra de navegación, debemos verificar dos cosas:

  1. A qué distancia está la barra de navegación de la parte superior de la pantalla
  2. Hasta dónde se ha desplazado el visitante

Podemos averiguar (1) con lo siguiente:

let navbar = document.getElementById("main-nav");
let navPos = navbar.getBoundingClientRect().top;

Para (2), primero debemos agregar un detector de eventos para detectar el desplazamiento y luego almacenar la posición de desplazamiento en una variable.

window.addEventListener("scroll", e => {
scrollPos = window.scrollY;
});

Agregar la clase fija a la barra de navegación

Genial, ahora tenemos la información que necesitamos. Cuando el usuario se desplaza, comprobaremos si la nueva posición de desplazamiento (scrollPos) es mayor que la posición de la barra de navegación (navPos) y, de ser así, agregaremos la clase.

¡Pero espere un segundo!

Cuando hacemos esto, estamos tomando un elemento relativamente posicionado y haciéndolo absoluto. Esto lo saca ‘del flujo’ del marcado, y cualquier elemento debajo de él saltará hacia arriba para llenar el espacio vacío que dejó atrás.

Para compensar esto, simplemente agregaremos 45 px de relleno al primer elemento después del encabezado, que en este caso es el elemento #tim-vine. Dado que la barra de navegación tiene una altura de 45 px, esto evitará que el contenido “salte” hacia arriba:

La nueva clase:

.navbarOffsetMargin {
padding-top: 45px;
}

… y el JS que hace que todo funcione:

let timVine = document.getElementById("tim-vine");

window.addEventListener("scroll", e => {
let viewportHeight = window.innerHeight;
let scrollPos = window.scrollY;
if (scrollPos > navPos) {
navbar.classList.add('sticky');
header.classList.add('navbarOffsetMargin');
} else {
navbar.classList.remove('sticky');
header.classList.remove('navbarOffsetMargin');
}
});

¡Pruébalo a continuación!

ver la pluma
en
CódigoPen.

5) Resalte las secciones activas de la barra de navegación

Con las barras de navegación, se acostumbra resaltar la sección del sitio en la que se encuentra actualmente el visitante.

La lógica aquí es muy similar a lo que acabamos de hacer con la barra de navegación. Primero, creamos una clase para cambiar los colores del enlace de la barra de navegación cuando está activo:

nav a.active {
color: #1e1e1e;
background: white;
}

También agregué 5px de relleno a nav a, para darle un poco de espacio para respirar, y agregué la clase activa a la primera sección, ya que el usuario aterrizará en esa sección:

<a href="#header" class="active">Home</a>

Ahora, todo lo que tenemos que hacer es agregar y eliminar esta clase de los elementos a dentro de la barra de navegación cuando la sección relevante esté a la vista.

Recomendado:  Seis ideas de marketing dental para hacer crecer su práctica

El nuevo JS que necesitamos para esto se muestra a continuación:

let navbarLinks = document.querySelectorAll("nav a");

window.addEventListener("scroll", e => {

scrollpos = window.scrollY;
if (scrollpos > (viewportHeight - navHeight)) {
navbar.classList.add('sticky')
} else {
navbar.classList.remove('sticky')
}

navbarLinks.forEach(link => {
let section = document.querySelector(link.hash);
if (scrollPos + 150 > section.offsetTop && scrollPos + 150 < section.offsetTop + section.offsetHeight ) {
link.classList.add("active");
} else {
link.classList.remove("active");
}
});
});

Repasando las nuevas adiciones línea por línea:

let navbarLinks = document.querySelectorAll("nav a");

Esto toma todos los elementos a dentro del elemento de navegación y los coloca en una matriz llamada navbarLinks.

navbarLinks.forEach(link => {

Recorreremos cada uno de nuestros enlaces y ejecutaremos el código dentro de este bloque. Dentro de este bloque, usaremos el alias ‘enlace’ para referirnos a nuestros enlaces.

let section = document.querySelector(link.hash);

link.hash se refiere a la URL de destino del enlace. Esta línea escanea la página en busca de un elemento con ese nombre y, si encuentra uno, lo almacena en la variable de sección.

Dado que los enlaces apuntan a las secciones dentro de la página, esto devolverá la sección a la que apunta el enlace.

Comprobar si la sección está actualmente en pantalla

if (scrollPos + 150 > section.offsetTop && scrollPos + 150 < section.offsetTop + section.offsetHeight ) {

Esto debería resultarte familiar: es similar a la lógica que usamos anteriormente. Aunque hay dos diferencias:

  1. Esta vez, también verificamos si la parte inferior del elemento (es decir, su offsetTop más su altura) es mayor que la posición de desplazamiento. Si es así, eso significa que el usuario se ha desplazado más allá, por lo que podemos eliminar la clase activa.

  2. Agregué 150 píxeles adicionales a window.scrollY. ¿Por qué? Bueno, imagine que se ha desplazado 1 píxel por encima de la parte superior de una sección.

En este caso, esa sección ocupa toda la pantalla, excepto ese píxel. Entonces, aunque la parte superior de la ventana gráfica no ha llegado oficialmente a esa sección, realmente parece que es en la que estás “en”. Además, recuerda que la barra de navegación fija ocupa 45 px de la pantalla.

Agregar el búfer de 150 px ayuda a ajustar esto un poco.

Por supuesto, no tiene que usar 150 px; use lo que le parezca correcto de acuerdo con el tamaño de la pantalla y la cantidad de contenido en la página.

     link.classList.add("active");
} else {
link.classList.remove("active");
}
});
});

Si se cumplen las condiciones anteriores, agregaremos la etiqueta activa al enlace. Si no, lo eliminamos. Luego, simplemente cerramos nuestros paréntesis y ¡estamos listos!

¿Qué pasa si quieres una barra de navegación verdaderamente fija?

Quizás se pregunte, ¿qué haría si quisiera tener la barra de navegación en la parte superior de la pantalla todo el tiempo, sin este efecto pegajoso?

Es fácil: simplemente configure el elemento de la barra de navegación con position: fixed y top: 0:

#main-nav {
background-color: #1e1e1e;
padding: 10px;
text-align: center;
width: 100%;
position: fixed;
top: 0;
box-sizing: border-box;
height: 45px;
}

Luego, elimine el JS que agregó la clase adhesiva, ya que no la necesitamos ahora. Y ¡listo!:

Recomendado:  Tecno Camon 18 y Camon 18P Especificaciones y precio

ver la pluma
en
CódigoPen.

6) Estrangulamiento del detector de eventos

Solo un paso más antes de que terminemos: si está utilizando el enfoque JS, es una buena idea acelerar las funciones en el detector de eventos.

¡No, no ese tipo de estrangulamiento! Esto es lo que quiero decir…

Cuando el usuario se desplaza, puede desencadenar 30, 50, tal vez incluso 100 eventos por segundo. No es un gran problema en nuestro pequeño proyecto aquí, pero en proyectos más grandes con funciones más amplias, esto podría ser un golpe de rendimiento innecesario.

La solución es estrangulamiento. Básicamente, cómo funciona es que, cada vez que llamas a la función, inicias un temporizador. Si intenta volver a llamar a la función antes de que se agote el tiempo, el acelerador no lo permitirá.

Entonces, ¿cómo configuramos esto? Fácil: ¡usa una biblioteca! Lodash es común. Simplemente descárguelo y cárguelo en su archivo HTML:

<script src="lodash.js"></script>

Una vez hecho esto, simplemente sacamos nuestro código del detector de eventos y lo metemos en una función:

function toggleClassesOnScroll() {
scrollpos = window.scrollY;
if (scrollpos > (viewportHeight - navHeight)) {
navbar.classList.add('sticky')
} else {
navbar.classList.remove('sticky')
}
navbarLinks.forEach(link => {
let section = document.querySelector(link.hash);
if (section.offsetTop <= window.scrollY + 300 &&
section.offsetTop + section.offsetHeight > window.scrollY + 300) {
link.classList.add("active");
} else {
link.classList.remove("active");
}
});
}

Ahora, normalmente llamaríamos a esa función desde dentro del detector de eventos:

window.addEventListener("scroll", e => {
toggleClassesOnScroll()
});

Sin embargo, con Lodash solo ponemos esa función en el acelerador, así:

window.addEventListener("scroll", e => {
_.throttle(toggleClassesOnScroll(), 100);
});

El 100 aquí solo significa 100 milisegundos. Cuando se llama a nuestra función, se inicia un temporizador de 100 milisegundos y la función no volverá a ejecutarse hasta que se agote ese temporizador.

Resultado final

ver la pluma
en
CódigoPen.

Bastante genial, ¿eh? Al cargar la biblioteca Lodash, abre todo un mundo de funciones de rendimiento y ajuste que puede usar, para evitar tener que escribir todo ese código usted mismo.

Otra biblioteca fantástica que quizás desee consultar es fullPage.js. Esto realmente llevará su sitio de una página al siguiente nivel. Con fullPage, las diferentes secciones de su sitio están bloqueadas en el tamaño de la ventana gráfica, y cuando el usuario se desplaza, se desplaza hacia abajo a la siguiente sección (y hay algunas animaciones elegantes para llegar allí, así como un desplazamiento suave).

Su navegador no soporta la etiqueta de vídeo.

Esto hace que todo lo que hemos estado hablando aquí sea mucho más fácil: es fácil verificar qué enlace de la barra de navegación está activo porque una página está activa a la vez. No hay necesidad de perder el tiempo calculando las compensaciones. ¡Así que eche un vistazo a fullPage.js y vea lo que piensa!

Artículos relacionados

Sobre el Autor:

warren davies es un desarrollador front-end con sede en el Reino Unido.
Puedes encontrar más de él en https://warrendavies.net