Advertisement
  1. Web Design
  2. Patterns

Cómo crear un encabezado fijo que se pone en movimiento al desplazarse la página.

by
Difficulty:BeginnerLength:MediumLanguages:

Spanish (Español) translation by Rodney Martinez (you can also view the original English article)

En este curso, aprenderemos como crear un modelo visto en muchos sitios web estos últimos días: un encabezado fijo, el cual se pone en movimiento hasta que desplazamos hacia abajo en la página. Empezaremos con una estructura básica, luego pondremos todo a trabajar usando CSS y código JavaScript por completo. Antes de cerrar, cubriremos en resumen cómo podemos optimizar nuestro código así como también discutiremos los desafíos que se presentan cuando aplicamos este tipo de modelo a dispositivos táctiles.

Para tener una idea de lo que vamos a crear, acá está una demostración (o si prefiere una visualización a pantalla completa):

Marcado HTML

Comenzaremos éste ejercicio con el siguiente marcado para el encabezado, un contenedor <nav> y un par de otros elementos anidados.

El elemento nav, el cual es parte del encabezado, contiene tres elementos; el logotipo, el menú principal y el botón que marca la posición para activar un menú flexible (debajo de los 1061 px).

Nota: Si usted presiona éste botón, nada grave pasará. Crear un menú flexible está más allá del alcance de este curso.

Inicial estilos CSS

Bien, veamos algunos estilos CSS para conseguir que las cosas se muevan:

Aquí está un breve explicación de las reglas más importantes acá:

  • El elemento header es un elemento en una posición fija.
  • Usamos flexbox para configurar el elemento nav.
  • El logotipo tiene un [margen-superior] margin-top: 50px y [margen-izquierdo] margen-izquierdo: 50px. Asimismo, le damos un [margen interno] padding: 20px 30px.
  • El menú principal refleja el logotipo con margin-top: 5px y margin-left: 50px.
  • El enlace del botón flexible está oculto. Se vuelve visible cuando la anchura de la ventanilla es menor que 1061px. Por otra parte, ajustamos los márgenes de la parte de arriba y de la derecha hasta 10px.
  • Añadimos la propiedad transition a los elementos cuyos valores de propiedad transición cambiarán en el futuro. En esta forma, logramos un efecto de transición suave entre el estado inicial y el final.

Con estas reglas preparadas, el encabezado luce así:

How the header initially looks like

Animando el Encabezado

Hasta ahora, hemos creado la estructura básica de nuestro encabezado. Ahora es el momento de discutir los siguientes pasos:

  • El elemento main debería estar ubicado debajo del encabezado. Recuerde que el encabezado tiene configurada la posición así: positioned: fixed, y además, está situado en la parte de arriba del elemento main.
  • El encabezado debería ser animado cuando nos desplacemos hacia abajo en la página.

Para solucionar la primera tarea, añadimos una propiedad padding-top al elemento main. El valor de ésta propiedad debería ser igual a la altura del encabezado. En nuestro caso, no hemos especificado una altura fija para nuestro encabezado, así que usaremos algunos códigos de JavaScript, para calcularlo, y luego añadimos el padding correspondiente al elemento main.

Para resolver la segunda función, haremos lo siguiente:

  1. Recuperar el número de pixeles que el documento ya ha desplazado hacia abajo.
  2. Si éste número es mayor que 150px asignamos la clase scroll al encabezado.

JavaScript

Aquí está un código necesario de JavaScript, comenzamos definiendo algunas variables, calculando la altura del header, luego añadiendo esos valores como el padding-top al elemento main:

Para esta demostración. usamos la propiedad offsetHeight para recuperar la altura del encabezado. Tenga en mente que igualmente podríamos haber usado el método getBoundingClientRect(). Vale la pena mencionar que éste método puede devolver valores fraccionales.

Ahora dentro del evento de desplazamiento: 

Acá tomamos ventaja de la propiedad de las ventanas; pageYOffset para calcular el número de pixeles que nuestro documento se ha desplazado verticalmente. Observe que ésta propiedad no funciona en versiones anteriores de IE (<9). Sin embargo, si desea respaldar cualquiera de éstas versiones, entonces puede encontrar un método alternativo aquí.

Después, usamos la propiedad classList para añadir o quitar la clase scroll de nuestro encabezado. Sin embargo, no todos los navegadores soportan esta propiedad, así que si desea respaldar cualquiera de éstas, entonces puede revisar los archivos classList.js y classie.js. Para este ejemplo, podríamos hacer utilizado la propiedad className para manipular nuestra clase, pero en un escenario en el mundo real, ésta no podría ser la solución  (en caso de que tengamos varias clases).

Para agilizar las cosas, llamaremos a nuestra función en dos diferentes casos:

  • Cuando la página cargue
  • y cuando cambiemos el tamaño de la ventana del navegador.

CSS

Siempre que nuestro desplazamiento exceda el límite de los 150px, algunas reglas se realizan:

Específicamente, hacemos los siguientes cambios:

  • Añadir una sobra gris al encabezado.
  • Reducimos el padding [los márgenes internos], del logotipo y la fuente.
  • Cambiamos la alineación para los objetos flex a través del eje transversal.
  • Eliminamos el margen del logotipo, del menú, y el enlace del botón responsive.

Las reglas mencionadas anteriormente da como resultado ésta nueva configuración del encabezado:

How the header looks like when our scrolling exceeds the limit of 150px

Ahora, hágamoslo Responsive [Flexible].

Como he mencionado en la sección anterior, cuando la anchura de la ventana del navegador es menor que 1061px, ocultamos el menú y mostramos el botón que activa la opción responsive (pero recuerde que de hecho, éste botón no ejecutará ninguna acción). Y, hacemos pocos cambios en los elementos seleccionados.

A continuación puede ver la apariencia inicial del encabezado responsive:

How the responsive header initially looks like

Aquí están las relacionadas reglas CSS:

Y aquí está la apariencia del encabezado una vez que ha sido animado:

How the responsive header looks like when our scrolling exceeds the limit of 150px

Consideraciones de Desempeño

Ahora que hemos logrado dar a nuestro encabezado el funcionamiento que deseamos, vamos a avanzar un poco más y discutiremos algunas cosas sobre el rendimiento.

En nuestro ejemplo, el código que manipula la animación del encabezado (por ejemplo, callbackFunc) se ejecuta cuando el evento scroll se activa. Esto significa que puede ser activado cientos de veces o más. Esto puede dar como resultado problemas de rendimiento, especialmente cuando la función callbackFunc contiene muchas cosas que debería realizarse cuando nos desplazamos hacia arriba o hacia abajo de la página. En nuestro caso específico, estamos tratando con una simple animación, pero imagine un escenario en el mundo real donde queremos hacer más cosas complejas como cambiar la posición de lo elementos y así sucesivamente.

Así que, ¿qué podemos hacer al respecto? Bueno, hay muchas soluciones posibles, pero por ahora; discutiremos brevemente una de ellas. Específicamente, queremos dejar que nuestra función sea ejecutada, como máximo una vez cada 200 mili-segundos (éste es un valor arbitrario).  Para implementar está funcionalidad, nos aprovecharemos de Lodash, la cual es una moderna biblioteca de utilidades de JavaScript. Esta biblioteca proporciona la función throttle que necesitamos. 

Primero, incluimos la biblioteca (afortunadamente también hay la opción para incorporar solamente la función deseada) en nuestro proyecto y luego reemplazamos éste código:

window.addEvenListener("scroll", callbackFunc);

con este:

window.addEventListener("scroll", _.throttle(callbackFunc, 200));

Para entender la diferencia, hagamos una prueba simple. Inicializaremos un contador que es incrementados cada vez que la función callbackFunc es activada.

Ahora, intente desplazarse hacia arriba y abajo de la página. Cuando lo haga, notará que el valor del contador cambia prácticamente cada 200ms. Después, repetiremos éste proceso sin usar Lodash. Usted notará que el valor del contador cambia mucho más rápido.

Otra vez, aunque esta optimización parece innecesaria para nuestro ejemplo sencillo, debería tenerla en consideración cuando esté trabajando con tareas costosas y repetitivas.

En la misma forma, podríamos haber optimizado el evento resize.

Respaldo del Navegador

Este efecto funciona en la mayoría de los navegadores y dispositivos recientes.  Sin embargo, la experiencia no es la misma en todos los dispositivos (por ejemplo, dispositivos iOS). Esto pasa porque el evento scroll funciona de forma diferente en los navegadores de escritorio en comparación a los dispositivos móviles. Por ejemplo, en un navegador de escritorio, el evento scroll se activa continuamente, mientras que en un iPad, esto ocurre cuando usted arrastra y suelta su dedo.

Conocer los problemas anteriores, es eficaz para que usted decida si o no es un modelo que podrá utilizar en sus páginas web.

Conclusión

En este curso, creamos un encabezado fijo, el cual es animado cuando nos desplazamos hacia abajo en la página. ¡Espero que le guste la demostración y que usted la use como inspiración en sus próximos proyectos!

Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.