Tipografía cinética en web: animar texto con CSS (2026)

La tipografía cinética está por todas partes en 2026: titulares que ganan peso al hacer scroll, palabras que respiran, letras que entran escalonadas. Lo que antes pedía librerías JavaScript o GIFs ahora lo montas con fuentes variables y CSS.

Aquí tienes el código de las cuatro técnicas más usadas, lo que cuesta cada una en rendimiento de verdad (spoiler: no todas son gratis, y la mayoría de artículos se equivocan en esto) y los dos límites de accesibilidad que no puedes saltarte.

Qué es la tipografía cinética

La tipografía cinética es la animación expresiva del tipo: cambios de peso, ancho, inclinación, posición o color que responden al tiempo, al scroll o a la interacción del usuario. No es «una palabra que rota». Es construir significado con el movimiento de la letra.

Bien aplicada, da personalidad y memorabilidad. Mal aplicada, distrae, provoca saltos de maquetación y deja fuera a parte de tu audiencia. La diferencia está casi siempre en el detalle técnico, no en el gusto.

Las 4 técnicas con su código

Antes de empezar, una nota que te va a ahorrar problemas: cuando animas el peso, el ancho o la inclinaciĂłn de una fuente variable, usa las propiedades CSS de siempre (font-weight, font-stretch, font-style), no font-variation-settings.

Esos tres ejes están registrados y ya tienen su propiedad. font-variation-settings queda reservado para ejes personalizados, los que van en mayúsculas como GRAD o SOFT. Si lo usas para el peso, pierdes la herencia y te complicas el mantenimiento sin ganar nada.

1. VariaciĂłn de peso con el scroll

El titular pasa de fino a negro conforme bajas. Se monta con animation-timeline: scroll(), sin JavaScript ni observadores.

@keyframes ganar-peso {
  from { font-weight: 200; }
  to   { font-weight: 800; }
}

.titular-cinetico {
  font-family: "Inter", sans-serif;  /* fuente variable */
  font-weight: 200;
}

@supports (animation-timeline: scroll()) {
  .titular-cinetico {
    animation: ganar-peso linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 60vh;
  }
}

El @supports no es opcional, y en el apartado de soporte te explico por qué. El animation-range limita el efecto a los primeros 60vh de scroll: sin él, la animación se estira por toda la página y el efecto se diluye.

2. RespiraciĂłn en loop (sin saltos)

El texto oscila de peso de forma cíclica. La versión ingenua anima font-weight, y ahí está la trampa: al cambiar el peso cambia el ancho de cada letra, el texto se recoloca y tienes un temblor constante.

La solución elegante es el eje GRAD (grade). Está diseñado justo para esto: cambia el peso aparente sin tocar el ancho de los glifos, así que los saltos de línea no se mueven. Roboto Flex lo trae.

@keyframes respirar {
  0%, 100% { font-variation-settings: "GRAD" 0; }
  50%      { font-variation-settings: "GRAD" 150; }
}

.respira {
  font-family: "Roboto Flex", sans-serif;
  animation: respirar 4s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .respira { animation: none; }
}

AquĂ­ sĂ­ toca font-variation-settings, porque GRAD es un eje personalizado y no tiene propiedad propia. Es la excepciĂłn a la regla de antes.

3. Hover con cambio de ancho

Al pasar el ratĂłn, la palabra se ensancha. Queda muy bien en menĂşs y enlaces destacados, siempre que reserves el espacio.

.nav-link {
  font-family: "Roboto Flex", sans-serif;
  font-stretch: 100%;
  transition: font-stretch 250ms ease-out;
  display: inline-block;
  min-width: 8ch;      /* reserva sitio: evita que salten los hermanos */
  text-align: center;
}

.nav-link:hover,
.nav-link:focus-visible {
  font-stretch: 125%;
}

El min-width y el focus-visible son lo que separa un efecto bonito de un menĂş que baila y que no se puede usar con teclado. No los quites.

4. Reveal por letras al cargar

Cada letra entra con un retardo escalonado. Es la única de las cuatro que anima solo opacity y transform, así que es la más barata de todas.

<h1 class="reveal" aria-label="Diseño en movimiento">
  <span aria-hidden="true" style="--i:0">D</span>
  <span aria-hidden="true" style="--i:1">i</span>
  <span aria-hidden="true" style="--i:2">s</span>
  <!-- ...resto de letras -->
</h1>
@keyframes aparecer {
  to { opacity: 1; transform: none; }
}

.reveal span {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.4em);
  animation: aparecer 400ms cubic-bezier(.2,.7,.3,1) forwards;
  animation-delay: calc(var(--i) * 40ms);
}

@media (prefers-reduced-motion: reduce) {
  .reveal span {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

FĂ­jate en el aria-label del h1 y en el aria-hidden de cada span. Sin eso, un lector de pantalla puede leer el titular letra por letra: «de, i, ese, e…». Es el fallo más grave de esta tĂ©cnica y casi nadie lo menciona.

Para partir el texto en letras sin hacerlo a mano, Splitting.js sigue siendo lo más cómodo. Pero comprueba que añade los atributos de accesibilidad, y si no, añádelos tú.

Rendimiento: lo que cuesta de verdad

Aquí viene la parte donde casi todos los artículos sobre tipografía cinética se equivocan, así que vamos con cuidado.

El navegador pinta en varias fases: estilo, layout, paint y composición. Solo transform y opacity se resuelven en la última, la de composición, que corre en la GPU y no bloquea el hilo principal. Todo lo demás cuesta más.

Animar peso o ancho de una fuente variable no lo maneja la GPU. El navegador tiene que volver a rasterizar los glifos en cada fotograma, y como el ancho de cada letra cambia, también recalcula el layout. Es más barato que animar font-size, pero no es gratis ni de lejos.

Propiedad animadaFase que disparaRecomendaciĂłn
transformSolo composiciĂłnSin reservas
opacitySolo composiciĂłnSin reservas
colorPaintAceptable en pocos elementos
font-variation-settings "GRAD"Paint (no altera métricas)Aceptable, la mejor para loops
font-weight, font-stretchLayout + paintSolo en 1-2 elementos y en tramos cortos
letter-spacingLayout + paintEvitar
font-sizeLayout + paintEvitar

Traducido a decisiones: un titular hero animando el peso no te va a hundir nada. Veinte elementos haciéndolo a la vez, en un móvil de gama media, sí. Si necesitas movimiento en muchos elementos, usa transform y opacity.

Y sobre el peso del archivo: una fuente variable no es gratis. Suele pesar más que un único peso estático, aunque bastante menos que cargar cuatro o cinco estáticos por separado. Si solo necesitas una variante, la variable te sale más cara.

El problema de los saltos de layout

Esto merece apartado propio porque afecta a Core Web Vitals. Cuando una letra cambia de peso, cambia su anchura de avance. Si el texto está en flujo normal, las palabras se recolocan, los saltos de línea se mueven y el bloque puede cambiar de alto. Eso es desplazamiento de diseño, y es la métrica CLS.

Tienes tres formas de esquivarlo:

  1. Usa el eje GRAD en lugar del peso. No cambia las métricas, así que no hay salto posible. Es la solución limpia para loops.
  2. Reserva el espacio con min-height en el contenedor o min-width en el elemento, calculado para el peso más ancho.
  3. Anima solo titulares de una línea, donde no hay reflujo de párrafo que estropear.

Un matiz importante: las animaciones que arranca el propio usuario (un hover, un scroll) suelen quedar fuera del cálculo de CLS. Las que se disparan solas, como un loop infinito, no. Por eso la respiración automática es justo el caso donde más falta hace el eje GRAD.

Accesibilidad: dos lĂ­mites no negociables

Uno: respeta prefers-reduced-motion. Hay personas para las que el movimiento en pantalla provoca mareo o migraña. No es una preferencia estética, es una necesidad. Ponlo como red de seguridad global:

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Dos: el texto tiene que seguir siendo texto. Si partes un titular en span por letra, añade aria-label en el contenedor y aria-hidden en los fragmentos, como te he puesto en la técnica 4. Si no, rompes la lectura para quien usa lector de pantalla.

Y tres cosas más de sentido común: no animes nunca texto crítico (llamadas a la acción, instrucciones, mensajes de error), mantén el contraste WCAG AA durante toda la animación (ojo con los fundidos que pasan por tonos intermedios) y no dejes nada parpadeando más de tres veces por segundo.

Soporte en navegadores y fallback

Las fuentes variables tienen soporte universal desde hace años: ahí no hay debate. Las animaciones ligadas al scroll son otra historia.

Chrome y Edge las soportan desde la versión 115. Safari también las tiene. Firefox va por detrás: a mediados de 2026 sigue detrás de un flag en la versión estable, activada por defecto solo en Nightly, y es una de sus prioridades de interoperabilidad para este año. El soporte global ronda el 84%.

Qué significa esto en la práctica: envuelve siempre el bloque en @supports (animation-timeline: scroll()) y diseña el estado sin animación para que se lea perfectamente. Es mejora progresiva, no degradación. Quien no la soporte verá el titular estático y no se enterará de que falta nada.

Si te interesa el tema más allá del texto, tengo un post sobre animaciones que se activan con el scroll.

Cuándo encaja y cuándo no

La tipografía cinética encaja bien en hero sections de marcas creativas, portfolios y agencias, páginas de producto premium con narrativa, y editorial digital. Si andas montando una, mira estos 20 ejemplos de hero sections inmersivas.

No encaja en comercio electrónico de gran volumen, donde el movimiento compite con el producto. Tampoco en webs de administración pública o salud, donde la accesibilidad manda. Ni en sitios con audiencia muy heterogénea o mayor, ni en aplicaciones donde lo que importa es entender rápido.

Si buscas presencia tipográfica fuerte sin movimiento, la tipografía exagerada te da un impacto parecido y no tiene ninguno de estos costes.

Errores tĂ­picos

  • Animar todos los titulares. Si todo se mueve, nada destaca. Uno por pantalla es suficiente.
  • Olvidar prefers-reduced-motion. El fallo de accesibilidad más comĂşn y el más fácil de arreglar.
  • Partir en letras sin aria-label. Convierte tu titular en una sopa de letras para el lector de pantalla.
  • Usar font-variation-settings para el peso. Para eso está font-weight.
  • Creerse que es gratis. Animar peso toca layout. Con moderaciĂłn, bien; a lo bruto, jank.
  • Duraciones mal calibradas. Para micro-interacciones y hovers, 200-400 ms. Para revelados narrativos puedes irte a 600-800 ms sin que se haga lento.
  • Meter GSAP para algo que resuelve CSS. Suma kilobytes sin aportar.

Preguntas frecuentes

¿Necesito JavaScript para hacer tipografía cinética?

Para las cuatro técnicas de este post, no: CSS y una fuente variable te bastan. Solo lo necesitas para partir texto en letras de forma automática (Splitting.js), o para efectos complejos tipo morfología de glifos o scrambling, donde GSAP sigue siendo la referencia.

ÂżAfecta al SEO?

No, mientras el texto siga siendo HTML real y no SVG ni canvas. Google lo lee sin problema. Un matiz: si partes el titular en un span por letra, asegĂşrate de que el texto completo sigue en el DOM en orden, y usa el aria-label igualmente por accesibilidad.

ÂżFunciona bien en mĂłvil?

Funciona, pero modera. La atención es más corta y la potencia de proceso menor, así que las animaciones que tocan layout se notan más. Acorta las duraciones y reduce el número de elementos animados en los breakpoints pequeños.

ÂżPenaliza Core Web Vitals?

Puede, y por dos vías. Por CLS si animas el peso de texto en flujo y las líneas se recolocan solas. Y por INP si saturas el hilo principal con muchas animaciones que tocan layout. Con el eje GRAD, espacio reservado y pocos elementos, no deberías ver movimiento en las métricas.

ÂżSirve para landings de conversiĂłn?

Con criterio, sĂ­. Un titular hero con respiraciĂłn sutil refuerza la marca sin robarle atenciĂłn al botĂłn. Lo que no debes animar es el elemento de conversiĂłn: si el botĂłn se mueve, la gente duda antes de pulsarlo.

¿Qué fuentes variables sirven para esto?

Cualquiera con eje de peso amplio te vale para la técnica 1. Para la respiración sin saltos necesitas una con eje GRAD, y Roboto Flex es la opción gratuita más completa (trae también ancho, inclinación y tamaño óptico). En Google Fonts puedes filtrar por fuentes variables y ver los ejes de cada una.

ÂżY si mi fuente no es variable?

Entonces olvida animar el peso: pasar de un archivo estático a otro produce un salto brusco, no una transición. Quédate con la técnica 4, que solo usa opacity y transform y funciona con cualquier tipografía.

ConclusiĂłn

La tipografía cinética no es decoración: es narrar con la letra. Pero tampoco es magia gratis, y ahí es donde se cae mucha gente. Animar peso toca el layout, las fuentes variables pesan, y partir un titular en letras puede romper la accesibilidad si lo haces sin cuidado.

Te aconsejo empezar pequeño: un solo titular, con el reveal por letras de la técnica 4, que es la más barata y la que menos riesgos tiene. En una tarde lo tienes montado. Cuando eso funcione, añade la respiración con GRAD. Disfrútalo!

Sigue por aquĂ­

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio