Kodflux
Kodflux
Crear cuenta gratisIniciar Sesión

CSS / HTML / Avanzado / 3 min

Barra de progreso de scroll en CSS

Indicador de lectura con CSS animation-timeline y fallback JavaScript para navegadores sin soporte.

Esta barra muestra cuánto avanzó el usuario en la lectura de una página.

El método principal usa CSS Scroll-Driven Animations con animation-timeline. Para Safari y navegadores sin soporte, el snippet incluye un fallback JavaScript con requestAnimationFrame.

Guía de Implementación Paso a Paso

  1. Pega el HTML al inicio de <body>.
  2. Añade el CSS en tu hoja global o dentro del <head>.
  3. Personaliza --progress-color y --progress-height.
  4. Mantén el fallback JavaScript para navegadores sin soporte.
  5. Prueba en una página larga para validar el cálculo de progreso.
HTML
<div id="kf-scroll-progress" role="progressbar" aria-label="Progreso de lectura" aria-valuemin="0" aria-valuemax="100"></div>

<style>
  :root {
    --progress-color: #3b82f6;
    --progress-height: 3px;
    --progress-z-index: 9999;
  }

  #kf-scroll-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: var(--progress-height);
    background: var(--progress-color);
    z-index: var(--progress-z-index);
    animation: scroll-progress linear;
    animation-timeline: scroll(root block);
    box-shadow: 0 0 10px var(--progress-color), 0 0 5px var(--progress-color);
    width: 0%;
  }

  @keyframes scroll-progress {
    from {
      width: 0%;
    }

    to {
      width: 100%;
    }
  }

  .kf-progress-gradient #kf-scroll-progress {
    background: linear-gradient(90deg, #3b82f6, #8b5cf6, #ec4899);
    box-shadow: none;
  }

  @media (prefers-color-scheme: dark) {
    :root {
      --progress-color: #60a5fa;
    }
  }

  @supports not (animation-timeline: scroll()) {
    #kf-scroll-progress {
      display: none;
    }
  }
</style>

<script>
(function() {
  if (CSS.supports('animation-timeline', 'scroll()')) return;

  const bar = document.getElementById('kf-scroll-progress');
  if (!bar) return;

  bar.style.display = 'block';
  bar.style.width = '0%';
  bar.style.transition = 'width 0.1s linear';

  let rafId;

  function updateProgress() {
    const scrollTop = window.scrollY || document.documentElement.scrollTop;
    const docHeight = document.documentElement.scrollHeight - window.innerHeight;
    const progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;

    bar.style.width = Math.min(progress, 100) + '%';
    bar.setAttribute('aria-valuenow', Math.round(progress));
    rafId = null;
  }

  window.addEventListener('scroll', function() {
    if (!rafId) {
      rafId = requestAnimationFrame(updateProgress);
    }
  }, { passive: true });

  updateProgress();
})();
</script>

Prompt para Codex

TEXT
Crea una barra de progreso de lectura/scroll usando CSS Scroll-Driven Animations con fallback en JavaScript vanilla.

Implementación CSS principal:
- <div id="kf-scroll-progress"> fijo en top: 0, left: 0, ancho variable, height configurable
- CSS custom properties: --progress-color, --progress-height, --progress-z-index
- animation: scroll-progress linear con animation-timeline: scroll(root block)
- @keyframes scroll-progress de width: 0% a width: 100%
- box-shadow con glow effect del mismo color
- Variante .kf-progress-gradient con gradiente azul → morado → rosa
- @media prefers-color-scheme: dark con color más claro
- @supports not (animation-timeline: scroll()) que oculte el elemento (lo mostrará el JS fallback)

Fallback JavaScript:
- Verificar con CSS.supports si el navegador soporta animation-timeline
- Si soporta: retornar
- Si NO soporta: mostrar el elemento y agregar listener scroll con requestAnimationFrame
- Calcular: (scrollY / (scrollHeight - innerHeight)) * 100
- Actualizar width y aria-valuenow

Incluir role="progressbar" y aria-label en el HTML.

Salida: HTML del elemento + bloque <style> + <script> de fallback, todo listo para usar.

Buscar en Kodflux