Títulos fijos en listado de posts usando GSAP y ScrollTrigger

En este artículo, mostraré cómo lograr un efecto donde los títulos de una lista de proyectos permanecen «fijos ó «sticky» mientras están visibles en el viewport. Para esto, usaremos la poderosa librería GreenSock (GSAP) y su plugin ScrollTrigger. Este es ideal para resaltar información clave en tus desarrollos web. Ahora, analicemos el código JavaScript que hace posible este efecto.

Ejemplo

Librerías necesarias

Antes de comenzar, asegúrate de incluir GSAP y el plugin ScrollTrigger en tu proyecto:

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>

Estructura HTML

<section class="section-text">
  <h1>Initial Section</h1>
</section>

<section class="section-images project-list">
  <div class="img">
    <div class="inner">
      <h3>Paul Jarvis</h3>
    </div>
    <img src="https://picsum.photos/id/13/1200/800">
  </div>
  <div class="img">
    <div class="inner">
      <h3>Jeffrey Kam</h3>
    </div>
    <img src="https://picsum.photos/id/46/1200/800">
  </div>
  <div class="img">
    <div class="inner">
      <h3>Cierra</h3>
    </div>
    <img src="https://picsum.photos/id/52/1200/800">
  </div>
  <div class="img">
    <div class="inner">
      <h3>Nicholas Swanson</h3>
    </div>
    <img src="https://picsum.photos/id/57/1200/800">
  </div>
  <div class="img">
    <div class="inner">
      <h3>Daniel Genser</h3>
    </div>
    <img src="https://picsum.photos/id/62/1200/800">
  </div>
  <div class="img">
    <div class="inner">
      <h3>Nicholas Swanson</h3>
    </div>
    <img src="https://picsum.photos/id/66/1200/800">
  </div>
</section>

<section class="section-text">
  <h2>End Section</h2>
</section>

Crea una sección con un contenedor para el texto:

Asegúrate de estilizar tu sección para que ocupe todo el alto de la ventana:

body {
  margin: 0;
  padding: 0;
  font-family: system-ui, sans-serif;
  background-color: #1e1e1e;
  color: #fff;
}

h1, h3, h4 {
  margin: 0;
}

h1,
h2 {
  font-size: clamp(1.25rem, 0.6944rem + 2.7778vw, 3.125rem);
}

img {
  width: 100%;
  height: auto;
}

section {
  background-color: #1e1e1e;
  min-height: 100svh;
}

.section-text {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

.section-images {
  padding: 2rem;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 2rem;
  background-color: #fff;
  align-items: start;
}

.section-images h3 {
  font-size: clamp(1.25rem, 0.6944rem + 2.7778vw, 3.125rem);
}

.section-images .img {
  position: relative;
}

.section-images .img:nth-child(4n + 1),
.section-images .img:nth-child(4n + 4) {
  grid-column: span 4;
}

.section-images .img:nth-child(4n + 2),
.section-images .img:nth-child(4n + 3) {
  grid-column: span 2;
}

.section-images .inner {
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 9;
  padding: 1rem;
}

Código JavaScript

Aquí está el código completo para lograr el efecto:

document.querySelectorAll(".project-list .img").forEach((obra) => {
  const inner = obra.querySelector(".inner");
  if (inner) {
    ScrollTrigger.create({
      trigger: inner,
      start: "top top",
      end: () => `+=${obra.offsetHeight - inner.offsetHeight}`,
      pin: true,
      pinSpacing: true
    });
  }
});

¿Cómo funciona este código?

Selección del texto:

  • Usamos document.querySelectorAll para seleccionar todos los elementos con la clase .img dentro de la lista .project-list.
  • Por cada elemento .img, buscamos su hijo con la clase .inner, que representa el título que queremos hacer «sticky».

Creación del ScrollTrigger:

  • Si el elemento .inner existe, configuramos un ScrollTrigger para él usando el método ScrollTrigger.create.
  • Configuración del ScrollTrigger:
  • trigger: Define el elemento que activa el efecto (en este caso, .inner).
  • start: Especifica que el efecto comienza cuando la parte superior del elemento .inner coincide con la parte superior del viewport («top top»).
  • end: Calcula el final del efecto sumando la diferencia entre la altura del contenedor (obra.offsetHeight) y la altura del título (inner.offsetHeight). Esto asegura que el título deje de estar sticky al final del contenedor.
  • pin: Activa la fijación del elemento, haciéndolo «sticky».
  • pinSpacing: Mantiene el espacio ocupado por el elemento fijado para evitar saltos en el diseño.

Conclusión

Este código demuestra cómo puedes utilizar GSAP y ScrollTrigger para mejorar la interactividad y el diseño de tu sitio web.

Administración de Productos en Woocommerce

En esta guía encontrarás dos tutoriales en video donde te enseño a crear y administrar productos en WooCommerce. Tabla de contenidos Crear un producto simple Crear un producto variable Agregar una nueva opción a un atributo Crear un producto variable con varios atributos Actualizar el inventario en productos simples y…