Solucionar e identificar problemas de Cumulative Layout Shift (CLS)
Aprende a encontrar y solucionar todos los problemas de Cumulative Layout Shift utilizando datos RUM, Chrome DevTools y correcciones específicas de CSS y HTML

Encontrar y solucionar problemas de Cumulative Layout Shift (CLS)
Esta página forma parte de nuestra serie sobre Cumulative Layout Shift (CLS). El CLS mide la estabilidad visual de tu página rastreando el movimiento inesperado del contenido. Una buena puntuación de CLS es inferior a 0.1, las puntuaciones superiores a 0.25 son deficientes. Si eres nuevo en el CLS, comienza con la página principal de CLS para conocer la fórmula, los umbrales y la mecánica de las ventanas de sesión.
El CLS es el Core Web Vitals con mejor rendimiento. Según el Web Almanac de 2025, el 72% de los sitios web aprueban el CLS a nivel mundial. Eso suena genial hasta que te das cuenta de que la mayoría de los desarrolladores nunca ven problemas de CLS en sus propias máquinas. Los cambios ocurren para los visitantes primerizos en conexiones lentas, y para cuando verificas en Chrome DevTools con tu caché activa, todo parece estar bien. Eso es exactamente lo que hace que el CLS sea complicado de depurar.
Esta guía se basa en el proceso exacto paso a paso que utilizo cuando asesoro sobre CLS. Primero datos CrUX y RUM, validar en Chrome y luego escribir la corrección.
Última revisión por Arjen Karel en marzo de 2026
CONSEJO DE CLS: El CLS se mide en ventanas de sesión, no como un total acumulado. El navegador agrupa los cambios de diseño en sesiones (máximo 5 segundos, espacios de 1 segundo entre cambios) y tu puntuación de CLS es la peor sesión. Una sola ráfaga de cambios durante la carga de la página puede hacer que falles en tu CLS, incluso si el resto de la visita es perfectamente estable.
Table of Contents!
Paso 1: Verificar CLS en Search Console
Antes de cambiar nada, confirma que realmente tienes un problema de CLS. Inicia sesión en Google Search Console, navega hasta Core Web Vitals y comprueba tanto en móviles como en escritorio.
Si Google está marcando URLs con "Problema de CLS: más de 0.25" o "Problema de CLS: más de 0.1", tienes la confirmación del Informe de Experiencia de Usuario de Chrome (CrUX) de que usuarios reales están experimentando cambios de diseño en tu sitio.
A diferencia del LCP y el INP, donde la potencia de cálculo en bruto y la velocidad de la red son importantes, los problemas de CLS pueden ser específicos del dispositivo o del tamaño de la pantalla. Cuando un problema similar afecta a móviles y escritorios (imágenes sin tamaño, intercambios de fuentes, contenido inyectado) debido al tamaño de la pantalla, el escritorio podría reportar un valor de CLS mucho mayor (porque una parte más grande del viewport visible puede verse afectada). Search Console agrupa las URLs, por lo que te dice qué tipos de páginas están afectadas, pero no qué elementos se están moviendo. Para eso necesitas monitorización RUM.

Paso 2: Identificar problemas de CLS con datos RUM
Search Console confirma que el problema existe, pero casi no te da nada con lo que trabajar. Necesitas averiguar qué elementos se mueven, en qué páginas y bajo qué condiciones. Para eso necesitas una herramienta RUM.
Construí CoreDash para responder exactamente a estas preguntas. Agregas una etiqueta de script y comienza a recopilar datos de atribución de CLS de cada visitante real. El punto de datos clave para la depuración del CLS es el elemento que se desplaza: el nodo del DOM real que se movió. Sin esa información, estás depurando a ciegas.
Encontrar elementos que se desplazan
Comienza mirando tus datos de CLS agrupados por elemento. En CoreDash, navega a la página de CLS y mira la tabla de datos ordenada por "CLS por Elemento". Esto muestra qué elementos causan el mayor cambio de diseño en todos tus visitantes. Haz clic en el peor para filtrar todas las métricas de las páginas donde ese elemento se desplazó.

Encontrar qué páginas están afectadas
Después de filtrar por el elemento que se desplaza de mayor impacto, revisa el desglose de URL. Los problemas de CLS pueden afectar a todo el sitio o a una plantilla entera. Ahora sabemos si el CLS está agrupado en tipos de página específicos: páginas de productos con galerías de imágenes, publicaciones de blog con espacios publicitarios o landing pages con animaciones hero. Saber qué páginas fallan te dice dónde enfocarte.
Comprobar visitantes nuevos frente a visitantes recurrentes
Esta es otra comprobación rápida que hago y que importa más de lo que la mayoría de la gente piensa. El CLS por intercambio de fuentes solo ocurre cuando la fuente no está en caché. El CLS de imagen por width: auto solo ocurre cuando la imagen no está en la caché del navegador. Si tu CLS es mucho peor para los visitantes primerizos, estás lidiando con un cambio dependiente de la caché que tú, como desarrollador, nunca verás en tu propia máquina a menos que desactives la caché (consejo: desactiva siempre tu caché de Chrome... pero esa es otra historia para otro día).
Comprobar tipos de dispositivos y tamaños de viewport
El CLS suele mostrar un patrón móvil/escritorio distinto al LCP y al INP. Los diseños responsivos pueden introducir cambios que solo aparecen en anchos y altos de viewport específicos. Un espacio publicitario que causaba problemas en el escritorio podría ni siquiera estar en el viewport móvil. Un menú de navegación podría animarse de forma diferente en puntos de interrupción más pequeños. Agrupa tus datos de CLS por tipo de dispositivo para saber dónde ocurren.
Paso 3: Depurar CLS con Chrome
Tus datos RUM te han dicho qué elementos se desplazan y por qué. Ahora reproduce el problema localmente y encuentra qué lo está causando.
Usar el Core Web Vitals Visualizer
La forma más rápida de ver los cambios de diseño es con la extensión de Chrome Core Web Vitals Visualizer. Carga la página, haz clic en el icono de la extensión y vuelve a cargar. Cada cambio de diseño se resalta con una superposición de color que muestra exactamente qué se movió y cuánto. Uso esto como mi primer paso antes de abrir el panel de Rendimiento porque da una respuesta visual inmediata.

Replicar las condiciones en Chrome y comprobar las capturas de pantalla de red
Los problemas de CLS suelen ser invisibles con una caché activa. Abre Chrome DevTools, desactiva la caché en la pestaña Red y limita la conexión a "Slow 4G" (mi favorita, te mostrará el CLS causado por condiciones de carrera). Ahora haz clic en el ícono de engranaje y desactiva el almacenamiento en caché (mientras DevTools esté abierto). Esto simula las condiciones que experimentan tus visitantes primerizos. Ve a la pestaña de red y habilita las capturas de pantalla. Ahora vuelve a cargar la página y observa los cambios.

Usar el panel de Rendimiento de Chrome
La mayoría de los cambios de diseño son fáciles de detectar cuando sabes cómo, pero a veces te eludirán. Ese es el momento de abrir Chrome DevTools (Ctrl+Shift+I) e ir al panel de Rendimiento para una depuración detallada. Presiona Ctrl+Shift+E para recargar y grabar. Después de que se cargue la página, desplázate hacia arriba y hacia abajo unas cuantas veces. Detén la grabación.
Busca la pista de "Layout Shifts". Cada cambio aparece como un bloque de color. Haz clic en un cambio para ver:
- El nodo que se desplaza: el elemento del DOM que se movió
- La puntuación del cambio: fracción de impacto multiplicada por la fracción de distancia
- hadRecentInput: si la entrada del usuario precedió al cambio (los clics y toques obtienen un período de gracia de 500 ms, pero el desplazamiento no)
Presta atención a cuándo ocurren los cambios. Los cambios durante la carga de la página apuntan a imágenes sin tamaño, intercambios de fuentes o transiciones CSS. Los cambios durante el desplazamiento apuntan a animaciones desencadenadas por el desplazamiento que usan propiedades de diseño.

Prueba rápida: desactivar todas las transiciones
Las transiciones CSS que animan propiedades de diseño son una causa furtiva de CLS porque solo cambian durante la fase de carga y son difíciles de reproducir. Pega este fragmento en la consola, recarga la página sin caché y compara el CLS:
document.head.insertAdjacentHTML('beforeend',
'<style>*{transition-property:none!important}</style>');
Si tu CLS disminuye después de desactivar las transiciones, has encontrado la causa. Usa la guía de depuración de transiciones CSS para encontrar las transiciones específicas responsables.
Medición de CLS con la API Layout Instability
La API Layout Instability te da acceso directo a cada cambio de diseño en JavaScript. Esta es la misma API que las herramientas RUM utilizan bajo el capó:
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (!entry.hadRecentInput) {
console.log('Layout shift:', {
value: entry.value,
sources: entry.sources?.map(s => ({
node: s.node,
previousRect: s.previousRect,
currentRect: s.currentRect
}))
});
}
}
});
observer.observe({ type: 'layout-shift', buffered: true });
El array sources muestra qué elementos se movieron. hadRecentInput filtra los cambios esperados de clics y toques. Para la medición en producción, usa CoreDash u otra herramienta RUM.
Paso 4: Solucionar problemas de CLS
Sabes qué elementos se desplazan y por qué. Es hora de solucionarlos. El CLS no tiene fases secuenciales como el LCP. En su lugar, los cambios de diseño tienen categorías de causas distintas. Aquí están las más comunes, en el orden en que las encuentro durante las auditorías.
1. Imágenes, videos e iframes sin dimensiones
Esta es la causa número uno de CLS en la web. El Web Almanac de 2025 informa que el 62% de las páginas móviles tienen al menos una imagen sin tamaño. La solución: incluye siempre los atributos width y height en las etiquetas <img>, <video> e <iframe>.
<img src="hero.jpg" width="800" height="450" alt="Descripción">
<style>
img {
height: auto;
max-width: 100%;
}
</style>
Ten cuidado con el width: auto en tu CSS. Esta única declaración anula el cálculo de la relación de aspecto del navegador y causa cambios de diseño incluso cuando has establecido el ancho y el alto en el HTML. He visto esto en docenas de sitios. El desarrollador hizo todo bien en el marcado, pero una regla CSS global como img { width: auto; height: auto; max-width: 100%; } lo deshizo todo. Para la explicación completa, consulta solucionar el cambio de diseño causado por el ajuste automático del tamaño de las imágenes. Para obtener una guía completa que cubra todas las causas de CLS de imágenes y medios (videos, iframes, dirección de arte, imágenes responsivas, lazy loading, marcadores de posición), consulta Cómo las imágenes y los medios causan Cumulative Layout Shift.
2. Intercambios de fuentes web
Cuando se carga una fuente web y reemplaza a la fuente de respaldo (fallback), la diferencia de tamaño causa un cambio de diseño. El Web Almanac de 2025 muestra que solo el 11% de las páginas precargan fuentes web. Eso significa que la gran mayoría de los sitios son vulnerables al CLS por intercambio de fuentes.
La solución tiene dos partes. Primero, haz que la fuente de respaldo coincida con las dimensiones de la fuente web utilizando anulaciones de métricas:
<style>
@font-face {
font-family: 'My Font Fallback';
src: local('Arial');
size-adjust: 105.2%;
ascent-override: 93%;
descent-override: 24%;
line-gap-override: 0%;
}
@font-face {
font-family: 'My Font';
src: url('/fonts/myfont.woff2') format('woff2');
font-display: swap;
}
body {
font-family: 'My Font', 'My Font Fallback', sans-serif;
}
</style>
Usa un Generador de Fuentes de Respaldo para calcular los valores de anulación correctos para tu par de fuentes. Segundo, acelera la entrega: aloja tus propias fuentes, precarga tu archivo de fuente crítico y usa WOFF2 con subconjuntos. Para una estrategia completa, consulta carga responsiva de fuentes web y asegurar que el texto permanezca visible durante la carga de la fuente web.
3. Animaciones y transiciones CSS
Según el Web Almanac de 2025, el 40% de las páginas móviles ejecutan animaciones no compuestas. Estas animan propiedades como width, height, top, left, margin y padding que desencadenan un recálculo de diseño en cada fotograma.
El infractor más común es transition: all. Cuando un desarrollador escribe transition: all .3s ease, cada cambio de propiedad se anima, incluidas las propiedades de diseño. Durante la carga de la página, los elementos que hacen la transición de su estado sin estilo a su estado con estilo producen cambios de diseño que ocurren de manera intermitente y son casi imposibles de reproducir de manera consistente. Veo este patrón todo el tiempo.
La solución: reemplaza las propiedades que desencadenan el diseño con propiedades compuestas.
- Usa
transform: translateY()en lugar detop/bottom - Usa
transform: translateX()en lugar deleft/right - Usa
transform: scale()en lugar dewidth/height - Usa
opacityen lugar devisibilitycombinado con cambios de altura - Nunca uses
transition: all. Especifica la propiedad exacta:transition: background-color .2s ease
transform y opacity se ejecutan completamente en el hilo del compositor y nunca activan el diseño. Para el proceso de depuración completo, consulta cambio de diseño causado por transiciones CSS.
4. Anuncios, incrustaciones y contenido inyectado dinámicamente
Los anuncios se cargan tarde y empujan el contenido hacia abajo. Los banners de consentimiento de cookies aparecen y desplazan la página. Las peticiones AJAX inyectan contenido nuevo sin reservar espacio primero. Todos estos son el mismo problema: algo aparece en la página que el navegador no conocía en el momento del renderizado.
La solución para todos estos es reservar espacio. Para los espacios publicitarios, establece un min-height que coincida con el tamaño esperado del anuncio:
<style>
.ad-slot {
min-height: 250px;
contain: layout style;
}
@media (min-width: 600px) {
.ad-slot { min-height: 90px; }
}
</style>
La declaración contain: layout style aísla el contenedor de anuncios del resto de la página. Para los banners de cookies, usa position: fixed para superponerlos en lugar de empujar el contenido hacia abajo. Para el contenido AJAX, reserva espacio con min-height. No necesitas una estimación exacta: un desajuste de 50px es mucho menos CLS que un cambio de 400px por no tener reserva de espacio.
Para incrustaciones de terceros como YouTube, Google Maps y widgets de chat, usa el patrón facade: muestra un marcador de posición estático y solo carga la incrustación real cuando el usuario interactúe con ella. Cero CLS, cero recursos desperdiciados.
5. Cambios de diseño provocados por el desplazamiento
Esta es la causa de CLS que Lighthouse nunca detectará. Lighthouse no desplaza la página, por lo que los cambios de diseño provocados por el desplazamiento son completamente invisibles en las pruebas de laboratorio. La única forma de encontrarlos es con datos RUM o grabando una traza en el panel de Rendimiento mientras te desplazas manualmente.
El ejemplo más común es un encabezado que se oculta al desplazarse y que anima la propiedad top. Aquí está lo que la mayoría de los desarrolladores no saben: el desplazamiento no es una entrada excluyente en la especificación de Layout Instability. Los clics y los toques obtienen un período de gracia de 500 ms. El desplazamiento no. Cada cambio de diseño desencadenado por el desplazamiento cuenta para tu puntuación de CLS.
La solución: usa transform: translateY() en lugar de top para cualquier animación desencadenada por el desplazamiento. Lo mismo se aplica a los efectos de paralaje (parallax), barras de navegación que se encogen y barras de progreso vinculadas al desplazamiento. Si se mueve al desplazarse, anímalo con transform. Para el recorrido completo con ejemplos en video, consulta cómo las animaciones desencadenadas por el desplazamiento causan CLS.
Lista de verificación de soluciones rápidas
| Causa de CLS | Cómo detectarlo | Solución |
|---|---|---|
| Imágenes/videos sin tamaño | Auditoría de Lighthouse "imágenes sin tamaño" | Añadir width y height; eliminar width: auto del CSS |
| Intercambios de fuentes web | RUM: CLS peor solo en la primera visita | Anulaciones de métricas de fuentes; precargar WOFF2; alojar tus propias fuentes |
| Transiciones CSS | Fragmento de consola para listar todas las transiciones | Reemplazar transition: all con propiedades específicas; usar transform/opacity |
| Anuncios de carga tardía | Atribución RUM mostrando elementos contenedores de anuncios | min-height en los espacios publicitarios; contain: layout style |
| Banners de consentimiento de cookies | Pico de CLS en la primera visita; banner en los datos de atribución | Usar superposición position: fixed en lugar de empujar el contenido |
| Animaciones de desplazamiento | Traza de Rendimiento al desplazarse; CLS de campo > CLS de laboratorio | Reemplazar top/left/height con transform |
Guías relacionadas
- Cómo las imágenes y los medios causan Cumulative Layout Shift: La guía completa sobre CLS proveniente de imágenes sin tamaño, videos, iframes, dirección de arte, imágenes responsivas, lazy loading y marcadores de posición.
- Solucionar el cambio de diseño causado por el ajuste automático del tamaño de las imágenes
- Cambio de diseño causado por transiciones CSS
- Animaciones desencadenadas por el desplazamiento y CLS
- Asegurar que el texto permanezca visible durante la carga de la fuente web
- Alojar tus propias Google Fonts
- Carga responsiva de fuentes web
Para obtener una descripción general completa de todos los Core Web Vitals, visita el centro de Core Web Vitals o utiliza la Lista de Verificación Definitiva de Core Web Vitals para auditar todo tu sitio.
Performance degrades the moment you stop watching.
I set up the monitoring, the budgets, and the processes. That is the difference between a fix and a solution.
Let's talk
