Cambio de diseño acumulado (CLS)

Qué mide Cumulative Layout Shift, cómo se calcula la puntuación (impacto × distancia), las ventanas de sesión, los umbrales, sus causas habituales y cómo corregirlo y depurarlo.

Publicado por primera vez: 26 jun 2026 · Última actualización: 8 ago 2026 · Avanzado
Idiomas

Cumulative Layout Shift (CLS) es la Core Web Vital de la estabilidad visual: cuánto contenido visible se mueve inesperadamente mientras se usa una página. Es una puntuación sin unidad (fracción de impacto × fracción de distancia por cambio) y, desde junio de 2021, toma la mayor ventana de sesión de cambios, no la suma de toda la vida. Bueno es ≤ 0,1 en el percentil 75 de los datos de campo; 0,1–0,25 necesita mejoras; > 0,25 es malo. Las causas habituales son imágenes, anuncios, iframes e incrustaciones sin tamaño, fuentes web y contenido inyectado sobre el pliegue; se corrigen reservando espacio (width/height o aspect-ratio), ajustando font-display y animando con transform. Lighthouse suele leer cerca de 0 porque no interactúa con la página ni ejecuta todo su ciclo de vida; los datos de campo (CrUX) son los que Google usa realmente para posicionar.

TL;DR — CLS es la Core Web Vital de la estabilidad visual. Cada cambio obtiene impact fraction × distance fraction; la métrica es la ventana de sesión más grande de cambios (≤ 1 s entre cambios y ≤ 5 s de ventana), no la suma de toda la vida de la página, que era la definición anterior a junio de 2021. Bueno es ≤ 0,1, necesita mejoras hasta 0,25 y es malo por encima de 0,25, en el percentil 75 de los datos de campo. Solo cuentan los cambios visibles en el viewport; los que ocurren dentro de 500 ms de una entrada discreta quedan excluidos, pero el desplazamiento no. Las causas son imágenes/vídeos/anuncios/iframes/incrustaciones sin tamaño, fuentes web y contenido inyectado sobre contenido existente; las soluciones son reservar espacio, font-display/size-adjust y animar solo con transform. La trampa: Lighthouse (laboratorio) suele leer casi 0 porque no interactúa con la página ni ejecuta todo su ciclo de vida; los datos de campo (CrUX) son los que Google mide realmente.

Qué mide CLS

La formulación de Google es: “Cumulative Layout Shift (CLS) is a stable Core Web Vital metric. It’s an important, user-centric metric for measuring visual stability because it helps quantify how often users experience unexpected layout shifts.” (traducción) «Cumulative Layout Shift (CLS) constituye una métrica estable de Core Web Vitals. Es una métrica importante y centrada en el usuario para medir la estabilidad visual porque ayuda a cuantificar con qué frecuencia los usuarios sufren cambios de diseño inesperados». La palabra clave es inesperado: contenido que se mueve solo, no porque el usuario haya hecho algo.

Forma parte del trío Core Web Vitals con Largest Contentful Paint (carga) e Interaction to Next Paint (capacidad de respuesta). LCP e INP se miden en milisegundos, pero CLS es la excepción: una puntuación de proporción sin unidad. Esto confunde constantemente. Un CLS de 0,05 no son 50 ms; no tiene unidad de tiempo.

La fórmula: impacto × distancia

Para cada cambio, Google lo define así:

layout shift score = impact fraction × distance fraction
  • Fracción de impacto “measures how unstable elements impact the viewport area between two frames” (traducción) «mide cómo afectan los elementos inestables al área del viewport entre dos fotogramas»: el área visible combinada que ocupaban los elementos móviles antes y después, como proporción del viewport.
  • Fracción de distancia “the greatest horizontal or vertical distance any unstable element has moved in the frame divided by the viewport’s largest dimension (width or height, whichever is greater).” (traducción) «es la mayor distancia horizontal o vertical que haya recorrido cualquier elemento inestable en el fotograma, dividida por la dimensión mayor del viewport (ancho o alto, la que sea mayor)».

Ambas dimensiones importan por separado. Un elemento pequeño que recorre casi toda la pantalla y uno grande que apenas se desplaza pueden obtener puntuaciones muy distintas. El ejemplo de web.dev: una fracción de impacto de 0.75 y una fracción de distancia de 0.25 producen un CLS de 0.1875.

One shift scores the visible area affected multiplied by the farthest movement relative to the viewport. Fuente: web.dev

Three cards form the equation. Impact fraction is 0.75: the visible viewport area affected between two frames. Distance fraction is 0.25: the farthest movement divided by the viewport's largest dimension. Multiplying them produces a unitless individual layout-shift score of 0.1875. CLS ultimately keeps the largest session-window total, not a lifetime sum of every shift.

© Patrick Stox LLC · CC BY 4.0 ·

Ventanas de sesión: la parte que casi todos entienden mal

Este es el hecho sobre CLS que más se afirma mal y el que más quiero que recuerdes. CLS no es la suma de todos los cambios durante la vida de la página. Antes lo era; eso cambió en junio de 2021.

Hoy: “CLS measures the largest burst of layout shift scores for every unexpected layout shift that occurs during the entire lifecycle of a page.” (traducción) «CLS mide el mayor conjunto de puntuaciones de cambios de diseño correspondiente a cada cambio inesperado durante todo el ciclo de vida de una página». Un conjunto es una ventana de sesión: “one or more individual layout shifts occur in rapid succession with less than 1-second in between each shift and a maximum of 5 seconds for the total window duration.” (traducción) «uno o más cambios individuales ocurren rápidamente, con menos de 1 segundo entre ellos y una duración total máxima de 5 segundos». CLS es la puntuación de la ventana más grande, no la suma ni la media.

Evidence for this claim CLS uses the largest session window of unexpected layout shifts, with gaps under one second and a maximum five-second window; recent discrete input can exclude a shift. Scope: Current CLS session-window and recent-input rules. Confidence: high · Verified: web.dev: Cumulative Layout Shift

¿Por qué cambió? La antigua definición que lo sumaba todo castigaba silenciosamente a las páginas de larga duración. Una SPA o un feed con desplazamiento infinito acumulaba más CLS solo por existir más tiempo, aunque cada cambio individual fuera pequeño y estuviera bien espaciado. El equipo de Chrome Speed Metrics pasó a una ventana de sesión máxima para no penalizar la duración y eligió el máximo en vez de la media para evitar el resultado absurdo de que arreglar un cambio secundario pequeño empeorara la puntuación. Cuando se desplegó el cambio, ningún origen obtuvo una puntuación peor, la mayoría no cambió y mejoró una parte de las páginas con interfaces lentas o desplazamiento infinito. Si lees un artículo antiguo que aún dice «suma de todos los cambios», está desactualizado.

Qué cuenta y qué no

Tres exclusiones determinan qué llega realmente a tu puntuación:

  • Lo que está bajo el pliegue no cuenta. Solo se puntúan cambios de contenido visible en el viewport actual. Un cambio al final de una página larga que el usuario nunca alcanza no tiene impacto. En la práctica, arreglar cambios dentro del viewport casi siempre ofrece más retorno que perseguir cambios muy abajo.
  • Los cambios iniciados por el usuario tienen una tolerancia de 500 ms. “Layout shifts that occur within 500 milliseconds of user input will have the hadRecentInput flag set, so they can be excluded from calculations.” (traducción) «Los cambios que ocurren dentro de los 500 milisegundos de una entrada del usuario tendrán activada la marca hadRecentInput, por lo que pueden excluirse de los cálculos». Google considera que los cambios “that occur in response to user interactions… are generally fine, as long as the shift occurs close enough to the interaction that the relationship is clear to the user.” (traducción) «que ocurren como respuesta a interacciones del usuario… suelen estar bien, siempre que sucedan lo bastante cerca de la interacción para que la relación sea clara». Abrir un acordeón o expandir un menú es un movimiento esperado y se perdona.
  • Pero desplazarse no da vía libre. La exclusión de 500 ms solo se aplica a eventos discretos: toque, clic o pulsación de tecla. Los gestos continuos (desplazamiento y zoom con dos dedos) no activan la ventana de exclusión. Si el contenido cambia mientras alguien se desplaza, sigue contando. Esta distinción aparece mal explicada en mucha documentación; respétala.
Evidence for this claim A layout shift occurring within 500 milliseconds of a qualifying recent user input has hadRecentInput set and is excluded from CLS. Scope: field and lab Confidence: high · Verified: Cumulative Layout Shift (CLS)

Umbrales y de dónde sale la puntuación

“To provide a good user experience, sites should strive to have a CLS score of 0.1 or less,” (traducción) «Para ofrecer una buena experiencia de usuario, los sitios deberían aspirar a una puntuación CLS de 0,1 o menos», medida en “the 75th percentile of page loads, segmented across mobile and desktop devices.” (traducción) «el percentil 75 de las cargas de página, segmentado entre dispositivos móviles y de escritorio». Las bandas completas son:

Evidence for this claim CLS is good at 0.1 or less and poor above 0.25, assessed at the 75th percentile of page loads. Scope: Current web.dev CLS field thresholds. Confidence: high · Verified: web.dev: Cumulative Layout Shift
  • Bueno: ≤ 0,1
  • Necesita mejoras: 0,1 – 0,25
  • Malo: > 0,25
Evidence for this claim CLS is good at 0.1 or less and poor above 0.25, assessed at the 75th percentile of page loads. Scope: Current web.dev CLS field thresholds. Confidence: high · Verified: web.dev: Cumulative Layout Shift

La línea de 0,1 no es arbitraria. La investigación de usuarios de Google descubrió que “levels of shift from 0.15 and higher were consistently perceived as disruptive, while shifts of 0.1 and lower were noticeable but not excessively disruptive.” (traducción) «los niveles de cambio de 0,15 o superiores se percibían sistemáticamente como molestos, mientras que los de 0,1 o inferiores se notaban, pero no resultaban excesivamente molestos». Eligieron 0,1 en parte porque las incrustaciones de terceros (anuncios y redes sociales) provocan cambios con tanta frecuencia que un umbral más estricto sería poco práctico para la web real.

La parte del percentil 75 de los datos de campo es decisiva, y nos lleva a la mayor trampa de medición.

Laboratorio frente a campo: por qué no coinciden las cifras

Aquí es donde más gente se quema. Lighthouse y otras herramientas de laboratorio suelen mostrar un CLS cercano a 0,0 mientras los datos de campo —y Google— muestran algo mucho peor. La diferencia no significa que una herramienta mienta; es una cuestión de alcance. Una prueba de laboratorio es una carga única, breve y guionizada: no se desplaza, no hace clic y no permanece abierta, así que solo captura cambios de la carga inicial. Los datos de campo (CrUX) agregan visitas reales de muchos usuarios, dispositivos y navegaciones durante una ventana móvil, y CLS se define en todo el ciclo de vida de la página: apertura de menús, carga diferida al desplazarse, anuncios tardíos y cualquier duración de sesión. Una prueba breve de laboratorio no puede observar estructuralmente la mayor parte de eso.

La regla práctica es: usa los datos de laboratorio para depurar un cambio concreto y los de campo para conocer tu puntuación real. Google posiciona con datos de campo de Chrome User Experience Report (CrUX), que aparecen en PageSpeed Insights y Search Console. Si Lighthouse lee 0,0 pero PageSpeed Insights muestra 0,18, trata el dato de campo como el que representa a tus usuarios y reproduce después el cambio en el laboratorio interactuando como lo haría un visitante real. Hay dos diferencias de alcance más: la mayoría de herramientas, incluida Lighthouse, no propaga los cambios de diseño de un iframe a la puntuación del documento padre aunque CrUX pueda reflejarlos, y el RUM basado en Layout Instability API hereda ese punto ciego; por eso tu monitorización propia puede explicar peor un número de CrUX que parece más malo que tu atribución de primera parte.

Las causas más comunes

En orden aproximado de frecuencia según lo que veo:

  1. Imágenes y vídeos sin dimensiones. Sin una altura reservada, todo lo que está debajo salta al cargar el contenido.
  2. Anuncios, incrustaciones e iframes sin espacio reservado. Las redes publicitarias sirven tamaños dinámicos y las incrustaciones no anuncian su altura antes de cargar.
  3. Contenido inyectado dinámicamente sobre contenido existente. Banners de cookies, barras de avisos, widgets «relacionados» y promociones tardías: todo lo que empuja lo que ya está en pantalla.
  4. Fuentes web (FOIT/FOUT). Si la fuente personalizada sustituye a la alternativa y sus métricas difieren, el texto se redistribuye.
  5. Animaciones de propiedades que activan el diseño. Animar top, left, margin, box-shadow o box-sizing obliga al navegador a recalcular el diseño en cada fotograma.

Las soluciones

Cada solución refleja su causa:

  • Imágenes/vídeo: reserva el espacio. Define atributos width y height para que el navegador calcule la proporción y mantenga la caja; combínalos con img { height: auto; width: 100%; } para el comportamiento adaptable, o usa la propiedad CSS aspect-ratio. En la mayoría de los sitios es la corrección de CLS con mayor efecto.
  • Anuncios/incrustaciones/iframes: reserva espacio también. Usa min-height o aspect-ratio en el contenedor. La guía de Publisher Tag de Google es tajante: “Setting a fixed height and width directly on the ad slot div is the most effective way to do this.” (traducción) «Definir directamente una altura y una anchura fijas en el div del espacio publicitario es la forma más eficaz de hacerlo». En espacios de varios tamaños, reserva el del tamaño configurado más grande. Baja el contenido tardío para que cualquier cambio residual quede bajo el pliegue.
  • Contenido dinámico: no lo insertes en el flujo. Reserva un marcador del tamaño final o superpón el contenido en vez de inyectarlo. Los esqueletos solo ayudan si coinciden exactamente con las dimensiones finales; incluso unos pocos píxeles de diferencia provocan otro cambio. Prefiere cargas activadas por el usuario («Cargar más») a inserciones sorpresa.
  • Fuentes: iguala las métricas. font-display: optional es el único valor con un riesgo de CLS prácticamente cero; swap reduce el texto invisible, pero puede provocar un cambio al sustituirse. Mejor aún, usa las anulaciones CSS size-adjust, ascent-override, descent-override y line-gap-override para ajustar la fuente alternativa a la web. Precarga las fuentes críticas.
  • Animaciones: solo transform. Anima con transform (translate, scale y rotate) en lugar de top/left/margin. Las animaciones basadas en transform se componen y no activan el diseño, así que no desplazan nada.

Cómo encaja CLS en el posicionamiento (mantén la proporción)

CLS es una entrada de la señal de experiencia de página de Google. Google dice que sus sistemas de posicionamiento usan Core Web Vitals, pero la documentación actual de Search no publica un peso exacto de CLS, una regla de desempate ni una garantía de posicionamiento. Trata cualquier mecanismo concreto —incluido «es un desempate»— como una aproximación de trabajo, no como un hecho documentado. Mi consejo constante para todo lo que escribo sobre Core Web Vitals es: entra en la banda «bueno» y sigue adelante. La mayoría de sitios no verá un aumento relevante de tráfico o negocio por bajar de 0,08 a 0,02, y una sola puntuación rara vez explica por sí misma un resultado de ingresos o conversiones. CLS es un requisito básico: hay que superar el umbral, pero no debe convertirse en el centro del programa SEO a costa de LCP, INP o, francamente, del contenido.

Dos notas operativas que evitan mucha confusión:

  • CrUX lleva un retraso de unos 28 días. Es una ventana móvil de 28 días, así que una corrección publicada hoy tardará semanas en registrarse por completo en PageSpeed Insights o Search Console. No te alarmes si la cifra no cambia mañana.
  • El elemento atribuido no suele ser la causa raíz. Layout Shift Attribution API indica qué elemento se movió, pero web.dev advierte que “it’s possible that these elements are only indirectly related to the ‘root cause’ of layout instability.” (traducción) «es posible que esos elementos solo estén relacionados indirectamente con la “causa raíz” de la inestabilidad del diseño». El texto que salta suele ser la víctima de una imagen sin tamaño situada por encima que carga tarde: corrige la causa, no el síntoma. Trabaja con un bucle de marca de tiempo y disparador: anota cuándo empezó el cambio, revisa qué más cambió en esa ventana —una petición de red, una imagen o fuente, un redimensionamiento o una clase/estilo— y considera el nodo atribuido una pista, no una prueba, hasta asociarlo con el disparador.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.