Introducción
En este tutorial detallado aprenderás a crear una barra de progreso de lectura para entradas de WordPress usando únicamente CSS y el conocido truco sticky: colocar el indicador dentro del contenedor de artículo y aprovechar las nuevas capacidades de animación ligada al desplazamiento (Scroll-Linked Animations) para actualizar la progresión sin JavaScript. Explico la estructura HTML recomendada para integrarlo en temas WordPress, el CSS completo, variantes y recomendaciones de compatibilidad y accesibilidad.
Resumen del concepto
La idea clave:
- Insertar un pequeño elemento (la barra) al principio del contenedor del artículo.
- Hacer que ese elemento sea position: sticky con top: 0, de modo que quede visible en la parte superior mientras se hace scroll dentro del artículo.
- Usar una animación ligada al scroll del propio artículo (mediante @scroll-timeline y animation-timeline) para transformar el ancho de la barra en función del progreso de lectura (0% → 100%).
- Todo se hace con CSS. En navegadores que no soportan Scroll-Linked Animations se aplica una alternativa visual estática o degradada.
Compatibilidad y consideraciones
- Soporte: Scroll-Linked Animations (@scroll-timeline) es una característica moderna. Está disponible en navegadores Chromium recientes (puede requerir versiones relativamente nuevas). Firefox y Safari pueden no soportarlo todavía o solo parcialmente.
- Degradado: incluye estilos CSS alternativos para navegadores sin soporte (barra estática, colores definidos). Si necesitas un apoyo perfecto en navegadores antiguos deberás añadir una versión con JavaScript (no incluida aquí porque el objetivo es CSS-only).
- Accesibilidad: la barra es puramente visual. Si quieres exponer el progreso a lectores de pantalla deberás usar atributos ARIA actualizados dinámicamente (eso requiere JS). Al menos evita colores con poco contraste y ofrece opción para desactivarla mediante una clase en el contenedor.
Markup (colocar en plantillas o en bloque HTML)
Coloca este pequeño bloque dentro de la plantilla de la entrada (por ejemplo en single.php justo antes del contenido) o como bloque HTML en el editor, envolviendo el contenido del post en un contenedor con clase. Ejemplo de marcado mínimo:
ltarticle class=post-contentgt
ltdiv class=reading-progress aria-hidden=truegt
ltdiv class=reading-progress__bargtnbsplt/divgt
lt/divgt
ltdiv class=entry-contentgt
lt!-- aquí va el contenido del post: the_content() --gt
lt/divgt
lt/articlegt
Nota sobre ubicación
La barra debe estar dentro del mismo elemento contenedor que envuelve todo el contenido de la entrada (.post-content en el ejemplo). Eso permite que la animación ligada al scroll se base en el contenedor del artículo (progreso de la entrada) y no en el documento entero.
CSS: implementación usando Scroll-Linked Animations
El siguiente CSS crea la barra, la pega en la parte superior mediante position: sticky y la anima según el desplazamiento del contenedor. Puedes pegarlo en style.css del tema o en Apariencia → Personalizar → CSS adicional.
/ ===========================
Barra de progreso (CSS-only)
=========================== /
/ Estilos base /
.post-content {
position: relative / necesario para que el timeline use este contenedor /
/ opcional: max-width, margin, padding según tu tema /
}
/ Contenedor visible sticky: permanece en la parte superior mientras se hace scroll dentro del artículo /
.reading-progress {
position: sticky
top: 0
z-index: 40
pointer-events: none / no interfiere con clicks /
height: 6px / altura total del área (puedes cambiar) /
background: transparent
display: block
}
/ Barra real que crece /
.reading-progress__bar {
height: 100%
width: 0%
transform-origin: left center
background: linear-gradient(90deg,#0ea5e9,#06b6d4) / personalizar colores /
will-change: width, transform
transition: background-color 0.2s ease
}
/ -----------------------
Scroll-linked animation
-----------------------
Define un timeline ligado al contenedor .post-content y anima la propiedad transform/width.
Nota: sintaxis y soporte pueden variar este ejemplo usa la sintaxis actual propuesta.
/
@scroll-timeline post-scroll {
source: selector(.post-content)
orientation: block
start: 0%
end: 100%
}
/ Usamos una animación que lleva la barra de 0 → 100% en el eje X (scaleX) /
@keyframes progress-scale {
from { transform: scaleX(0) }
to { transform: scaleX(1) }
}
.reading-progress__bar {
transform: scaleX(0)
transform-origin: left center
animation: progress-scale 1 linear paused
animation-timeline: post-scroll
animation-fill-mode: both
}
/ Opcional: suavizado cuando carga o en navegación interna /
.reading-progress__bar {
transition: opacity 200ms ease, background-color 200ms ease
}
/ Fallback elegante para navegadores sin soporte: mostrar una barra base (estática) /
@supports not (animation-timeline: post-scroll) {
.reading-progress__bar {
width: 100%
max-width: 0%
background: linear-gradient(90deg,#0ea5e9,#06b6d4)
/ Simula progreso con un degradado lateral: (ver personalización) /
background-size: 0% 100%
background-repeat: no-repeat
/ Si quieres, muestra una barra mínima para indicar la funcionalidad /
opacity: 0.6
}
}
Explicación técnica del CSS
- La regla @scroll-timeline crea un timeline llamado post-scroll cuyo origen es el selector .post-content. Eso hace que la animación se sincronice con el desplazamiento dentro del artículo.
- La animación progress-scale transforma la barra desde scaleX(0) a scaleX(1). Con transform-origin en la izquierda obtenemos un crecimiento horizontal.
- animation-timeline: post-scroll liga la animación al timeline. La duración se mapea automáticamente al progreso del scroll (de 0% a 100% del scroll del contenedor).
- El contenedor .reading-progress es sticky, de modo que la barra permanece fija en la parte superior del viewport mientras se hace scroll dentro del artículo.
Cómo integrarlo en un tema WordPress (ejemplo PHP)
Si editas el archivo single.php de tu tema, inserta la marca justo antes del loop o dentro del template part que imprime el contenido. Ejemplo mínimo:
lt?php
/ dentro de single.php o content-single.php, alrededor de the_content() /
?gt
ltarticle id=post-lt?php the_ID() ?gt gt
ltdiv class=reading-progress aria-hidden=truegt
ltdiv class=reading-progress__bargtnbsplt/divgt
lt/divgt
ltdiv class=entry-contentgt
lt?php the_content() ?gt
lt/divgt
lt/articlegt
Personalizaciones comunes
- Altura y colores: modifica .reading-progress { height: Xpx } y el background de .reading-progress__bar.
- Posición fija en toda la página: si quieres que la barra cubra todo el sitio y no sólo el post, mueve .reading-progress fuera del .post-content y usa source: selector(body) o no uses timeline ligado al selector (pero ese caso deja de ser progreso por artículo).
- Ocultarla en móviles: usa media queries para ocultar la barra bajo cierto ancho de pantalla.
- Animación más suave: puedes cambiar keyframes para usar easing en ciertas partes o usar transform-origin distinto si deseas otras direcciones.
Fallbacks y qué hacer si tu navegador no soporta @scroll-timeline
Si el navegador no lo soporta verás la regla @supports not aplicada. Si necesitas soporte total cross-browser sin JS, las opciones son limitadas. Posibles soluciones:
- Mantener una versión simplificada (barra decorativa estática) para navegadores sin soporte.
- Ofrecer una opción con JavaScript para actualizar inline styles / atributos aria y así cubrir todos los navegadores (esto ya no sería solo CSS).
- Informar a los usuarios que usen navegadores modernos para ver la animación completa.
Consejos finales y buenas prácticas
- Mantén contraste suficiente entre la barra y el fondo para accesibilidad.
- Evita impedir la interacción: usa pointer-events: none en el contenedor para no bloquear enlaces o controles que queden debajo en el header.
- Si usas un builder o editor de bloques, inserta la estructura HTML en un bloque HTML y añade el CSS en el CSS del tema o en CSS adicional.
- Prueba en varias entradas de diferentes longitudes: la animación ligada al scroll mapeará correctamente el progreso independientemente de la longitud si el contenedor está bien definido.
Resumen
Con el truco sticky y las Scroll-Linked Animations puedes crear una elegante barra de progreso de lectura en WordPress sin JavaScript, manteniendo la barra dentro del contenedor del post y pegada visualmente arriba mediante position: sticky. Ten en cuenta la compatibilidad actual de la especificación y proporciona un degradado visual para navegadores sin soporte si lo deseas.
Ejemplo completo: HTML CSS (todo junto)
Aquí tienes un bloque combinado listo para copiar (coloca la parte HTML en el template o bloque HTML y el CSS en el stylesheet):
lt!-- HTML --gt
ltarticle class=post-contentgt
ltdiv class=reading-progress aria-hidden=truegt
ltdiv class=reading-progress__bargtnbsplt/divgt
lt/divgt
ltdiv class=entry-contentgt
lt!-- the_content() --gt
lt/divgt
lt/articlegt
lt!-- CSS (añádelo a tu style.css) --gt
ltstylegt
.post-content { position: relative }
.reading-progress { position: sticky top: 0 z-index: 40 height: 6px pointer-events: none }
.reading-progress__bar { height: 100% transform-origin: left center background: linear-gradient(90deg,#0ea5e9,#06b6d4) transform: scaleX(0) }
@scroll-timeline post-scroll { source: selector(.post-content) orientation: block start: 0% end: 100% }
@keyframes progress-scale { from { transform: scaleX(0) } to { transform: scaleX(1) } }
.reading-progress__bar {
animation: progress-scale 1 linear paused
animation-timeline: post-scroll
animation-fill-mode: both
}
/ Fallback /
@supports not (animation-timeline: post-scroll) {
.reading-progress__bar { width: 0 opacity: 0.6 background-size: 0% 100% }
}
lt/stylegt
Observación final
Este enfoque ofrece una solución elegante y totalmente CSS para navegadores modernos. Si necesitas soporte completo retroactivo, la alternativa es emplear un pequeño script JavaScript para calcular el scroll y establecer inline styles (no mostrado aquí por petición de mantener la solución CSS-only).
Leave a Reply