Cumulative Layout Shift (CLS): cómo medir y eliminar los saltos de diseño en tu web
Tabla de contenidos
Ibas a pulsar "Comprar", el contenido se movió y pulsaste otra cosa. Eso es el Cumulative Layout Shift (CLS): la métrica de estabilidad visual de las Core Web Vitals, y casi siempre tiene una causa concreta que se puede eliminar.
Qué mide el Cumulative Layout Shift (CLS): estabilidad visual, no velocidad
El CLS cuantifica con qué frecuencia los usuarios sufren desplazamientos inesperados del contenido. A diferencia del LCP (segundos) o del INP (milisegundos), es una puntuación sin unidades: resume cuánto se movió lo que el usuario miraba y hasta dónde llegó.
No todo desplazamiento es un problema. Si el contenido se mueve porque el usuario hizo clic o pulsó una tecla, el navegador lo considera esperado y no lo penaliza. Lo que cuenta es el movimiento que nadie pidió, y su daño está documentado en la propia documentación oficial del CLS: un salto puede hacer que alguien confirme un pedido que quería cancelar. Si buscas el marco general de las tres métricas, empieza por qué son las Core Web Vitals.
Un movimiento en tres pasos: carga asíncrona, elementos nuevos y dimensiones desconocidas
El patrón se repite: algo se carga de forma asíncrona, aparece por encima de contenido ya visible y lo empuja hacia abajo porque nadie reservó su espacio.
- Imágenes y vídeos sin dimensiones: el navegador no sabe cuánto alto reservar hasta descargarlos.
- Fuentes web con métricas distintas a las de la tipografía de reserva.
- Anuncios, widgets y embeds que se autoredimensionan al llegar su contenido definitivo.
Cómo se calcula el CLS: impact fraction x distance fraction
El CLS no mide "cuánto se movió algo", sino cuánto y hasta dónde. La fórmula oficial es layout shift score = impact fraction x distance fraction, sobre el viewport y los elementos inestables entre dos fotogramas.
- Impact fraction: el tamaño de la zona afectada, es decir, la unión del área visible del elemento en el fotograma anterior y el actual, como fracción del viewport. Si cubre el 75 % de la pantalla, es 0,75.
- Distance fraction: la mayor distancia que se movió un elemento, dividida por la dimensión mayor del viewport. Si bajó una cuarta parte de la altura, es 0,25.
Con esos números la puntuación de ese fotograma es 0,75 x 0,25 = 0,1875. Detalle que casi nadie menciona: solo cuentan los elementos que ya existían y cambian su posición inicial. Lo que salta suele ser la víctima: la causa está encima.
La ventana de sesión: tu peor racha, no tu suma
Desde Chrome 91 el CLS no es la suma de todos los desplazamientos, sino la puntuación de su peor racha: la ventana de sesión, con menos de 1 segundo entre shifts y un máximo de 5 segundos de duración total. Conviene saberlo porque la ayuda de Search Console todavía lo describe como "la suma total de todas las puntuaciones de shift". Y ojo con la excepción: los desplazamientos dentro de los 500 ms posteriores a un clic, un tap o una tecla se excluyen, pero el scroll, el arrastre y el pinch no cuentan como input reciente. Si el contenido se mueve mientras deslizas el dedo, ese shift sí suma.
Los umbrales y los datos de hoy: 0,1 en el percentil 75
Los umbrales oficiales no se han movido: bueno hasta 0,1, mejorable hasta 0,25 y malo por encima de 0,25. Se miden sobre el percentil 75 de las cargas de página y se segmentan entre móvil y escritorio. Una página solo aprueba si las tres Core Web Vitals están en verde en ese percentil.
| Métrica | Orígenes con valor bueno (CrUX, agosto 2026) |
|---|---|
| CLS | 81,5 % |
| INP | 85,3 % |
| LCP | 68,1 % |
| Las tres a la vez | 55,6 % |
Datos del Chrome UX Report: el CLS es la métrica con más aprobados tras el INP.
Cómo medir el CLS: primero campo, después laboratorio
Empieza por los datos de campo. El informe de Core Web Vitals de Search Console agrupa URLs con una ventana de 28 días: la columna "Group CLS" significa que el 75 % de las peticiones tuvieron esa puntuación o menos, y el estado del grupo lo determina su peor métrica. Como complemento, PageSpeed Insights para ver campo y laboratorio juntos, y web-vitals con onCLS() si mides desde tu propio panel.
Después el laboratorio, para reproducir: en Chrome DevTools, el panel Performance incluye un track de Layout shifts con marcadores proporcionales a cada salto y el insight de culpables. Lighthouse añade auditorías como las imágenes sin width y height. Aviso clave: los elementos de esa lista suelen ser víctimas; la causa está en el que se insertó encima.
img { width: 100%; height: auto; }
.contenedor-anuncio { min-height: 280px; }
El laboratorio mide solo la carga inicial; el campo, toda la vida de la página. Si PageSpeed Insights muestra un CLS bajo y el informe de campo uno alto, tienes CLS posterior a la carga: carga diferida sin espacio reservado al hacer scroll, contenido que cambia al pasar el puntero o transiciones de más de 500 ms.
Las cuatro causas que explican casi todo el CLS
- Imágenes y vídeos sin dimensiones: el navegador no puede reservar el alto hasta descargarlos.
- Anuncios, embeds e iframes: la mayor fuente de CLS del web real, porque su tamaño depende de lo que sirvan.
- Contenido inyectado: avisos de cookies, banners, listas que se reordenan o resultados que se añaden arriba.
- Fuentes web: el texto se maqueta con la tipografía de reserva y se sustituye al llegar la real.
Cómo arreglar el CLS, causa por causa
La regla de oro es una: si el navegador ya sabe cuánto va a ocupar un elemento, no hay salto.
Imágenes, anuncios y contenido dinámico: reserva el hueco
En imágenes y vídeos, declara width y height sin unidades y acompaña con img { width: 100%; height: auto; }: el navegador calcula la proporción al procesar el HTML y reserva el alto antes de la descarga. Para el resto del trabajo de imágenes y carga diferida, enlazo en lugar de repetirlo: optimización de imágenes para SEO y carga de imágenes con lazy loading.
En anuncios y embeds, reserva con min-height o aspect-ratio. No colapses el hueco cuando no se sirve anuncio: quitar ese espacio genera tanto CLS como insertarlo. Si no puedes reservarlo, coloca el contenido tardío lo más abajo posible en el viewport. En contenido dinámico, reemplázalo en un contenedor de tamaño fijo o tras una acción del usuario, y si va a tardar más de 500 ms, reserva el espacio esperado dentro de esa primera ventana.
Animaciones y fuentes: transform y font-display optional
Animar top, left, width, height o box-shadow provoca un re-layout y cuenta como desplazamiento; animar con transform no. En tipografías, font-display: optional hace que la fuente propia solo se use si está lista para el primer pintado. Elige además una reserva parecida y ajusta sus métricas con size-adjust y los *-override: está detallado en las buenas prácticas de fuentes.
Qué ha cambiado en 2026 (y por qué no es 2021 otra vez)
Según el changelog oficial de Chromium, la Layout Instability API reporta ahora sus rectángulos en píxeles CSS, en línea con getBoundingClientRect(), en lugar de píxeles físicos. La puntuación del CLS no cambia: lo que hay que actualizar son los paneles y el RUM que asumían píxeles físicos.
En aplicaciones de una sola página el CLS se puede segmentar por navegación suave, pero el informe de campo todavía no define cómo las reportará. Y no hay que buscar una métrica nueva: el CLS está marcado como estable y su umbral no se ha movido. La que se retiró en marzo de 2024 fue FID, sustituida por INP.
Errores frecuentes al optimizar CLS
- Perseguir una puntuación perfecta en laboratorio y no mirar el percentil 75 de los datos de campo.
- Confundir la víctima (lo que se movió) con la causa (lo que se insertó encima).
- Olvidar el CLS posterior a la carga: scroll, carga diferida y transiciones.
CLS y SEO: lo que Google dice de verdad
Google documenta en su guía de page experience que no existe una única señal de experiencia de página, que las Core Web Vitals sí las usan sus sistemas centrales de ranking y que el resto de aspectos de experiencia no ayudan directamente a posicionar. Traducido: mejorar el CLS no es un truco de posicionamiento, es evitar fricción y clics perdidos.
Conclusión: la lista de comprobación en seis pasos
- Mira el informe de Core Web Vitals en móvil y escritorio y prioriza las URLs en estado Poor.
- Compara campo y laboratorio: si el campo es peor, busca CLS posterior a la carga.
- Pon
widthyheight(oaspect-ratio) a todas las imágenes, vídeos y embeds. - Reserva espacio para anuncios y no colapses el hueco.
- Cambia animaciones de layout por
transformy aplicafont-display: optional. - Vuelve a medir con los mismos datos de campo y espera la ventana de 28 días.