La experiencia frustrante de pulsar un botón que se mueve
Has vivido esta situación: estás leyendo un artículo en el móvil, llegas a un enlace que quieres seguir, tu dedo se dirige hacia él, y en el instante exacto en que vas a tocarlo, un banner publicitario se carga por encima y todo el contenido se desplaza hacia abajo. En lugar de hacer clic en el enlace, has pulsado un anuncio que no querías ver. O peor aún: has confirmado una compra en lugar de cancelarla porque el botón se movió justo antes de que tu dedo tocara la pantalla.
Esta frustración tiene un nombre técnico: Cumulative Layout Shift (CLS), una de las tres métricas de Core Web Vitals que Google utiliza como señal de ranking. El CLS cuantifica cuánto se desplazan inesperadamente los elementos visibles de una página durante su carga y uso. Google establece que un CLS inferior a 0.1 es bueno, entre 0.1 y 0.25 necesita mejora, y por encima de 0.25 es deficiente.
El CLS no solo afecta a la experiencia del usuario (lo que ya sería razón suficiente para corregirlo), también es un factor de ranking directo. Según datos del Web Almanac de HTTPArchive publicados en 2025, el 38% de los sitios web en móvil tienen un CLS superior a 0.1, lo que significa que más de un tercio de la web entrega una experiencia visual inestable que Google penaliza. Y el impacto en negocio es medible: un retailer europeo documentó un incremento del 15% en conversiones tras reducir su CLS de 0.25 a 0.05, un cambio que no alteró el contenido ni el diseño, solo la estabilidad con la que se presentaba.
Qué es el CLS y por qué Google lo penaliza
El Cumulative Layout Shift es una métrica que cuantifica la suma de todas las puntuaciones de layout shift inesperado que ocurren durante toda la vida de una página. Cada shift individual se calcula multiplicando dos factores: la fracción de impacto (el porcentaje del viewport que ocupan los elementos desplazados) y la fracción de distancia (cuánto se han movido esos elementos respecto al viewport).
Un detalle técnico crítico: el CLS solo cuenta los shifts inesperados. Si el usuario hace clic en un botón y el contenido se expande como resultado directo de esa interacción, ese movimiento no cuenta como CLS porque es esperado por el usuario. Solo los desplazamientos que ocurren sin interacción del usuario — durante la carga, por inyección de contenido dinámico, o por redimensionamiento de elementos — contribuyen a la puntuación.
Google modificó la forma de calcular el CLS en 2021, pasando del acumulativo total a un modelo de “ventana de sesión” que agrupa los shifts ocurridos en intervalos de 5 segundos, con máximo 1 segundo entre shifts. La puntuación final es la ventana con mayor acumulación, no la suma total. Este cambio benefició a las single-page applications (SPAs) y a las páginas con contenido que se carga progresivamente, ya que un shift tardío no arrastra toda la puntuación.
Google penaliza el CLS alto porque la estabilidad visual es un componente fundamental de la experiencia de página. Un documento publicado por Google Search Central establece que la experiencia de página incluye Core Web Vitals como señales de ranking, y el CLS es una de las tres métricas evaluadas. No es el factor más determinante — la relevancia del contenido sigue siendo prioritaria — pero en escenarios competitivos, la diferencia entre un CLS de 0.05 y uno de 0.30 puede ser la diferencia entre posicionar en la primera o segunda página.
Cómo medir el CLS: herramientas y qué reportan
Medir el CLS correctamente requiere entender la diferencia entre datos de laboratorio y datos de campo, porque los resultados pueden ser significativamente diferentes.
Datos de campo (CrUX). Chrome UX Report recoge datos reales de usuarios de Chrome que visitan tu sitio. Representan la experiencia real y son los que Google utiliza para ranking. Se accede a ellos a través de PageSpeed Insights (la sección “Descubrir lo que experimentan los usuarios reales”), Google Search Console (informe de Core Web Vitals), y la API CrUX. Los datos de campo se actualizan con un periodo acumulativo de 28 días.
Herramientas como Lighthouse, DevTools Performance y WebPageTest simulan una carga en condiciones controladas. Son útiles para diagnóstico pero tienen una limitación importante: solo miden el CLS durante la carga inicial, no durante la interacción del usuario. Una página con un CLS de 0 en laboratorio puede tener un CLS de 0.4 en campo si los anuncios se inyectan después de la carga o si una fuente web causa un reflow tardío.
Chrome DevTools es la herramienta de diagnóstico más precisa. En la pestaña Performance, graba una carga de página y busca las barras rojas etiquetadas como “Layout Shift” en la sección Experience. Cada barra muestra qué elementos se movieron, cuántos píxeles se desplazaron y la puntuación individual del shift. La vista de Rendering con la opción “Layout Shift Regions” activada resalta visualmente las zonas que se mueven durante la carga.
Web Vitals Extension de Chrome muestra el CLS en tiempo real mientras navegas, actualizando el valor con cada shift que ocurre. Es la forma más rápida de verificar el CLS durante la interacción normal con la página.
Search Console reporta el CLS a nivel de grupo de URLs, clasificándolas como “Bueno”, “Necesita mejora” o “Deficiente”. Es el panel de monitorización más importante porque refleja exactamente lo que Google evalúa para ranking.
Las causas más frecuentes de CLS alto
Las causas de CLS alto se pueden agrupar en cinco categorías, ordenadas por frecuencia según datos del Web Almanac de HTTPArchive 2025:
1. Imágenes y vídeos sin dimensiones (40% de los problemas). Cuando una etiqueta <img> no tiene atributos width y height, el navegador no puede reservar espacio para la imagen antes de descargarla. Al cargarse, la imagen empuja todo el contenido que está debajo, generando un layout shift. El mismo problema afecta a los elementos <video> e <iframe>. La solución es declarar siempre width y height en el HTML, o usar la propiedad CSS aspect-ratio para reservar el espacio proporcionalmente.
2. Contenido inyectado dinámicamente (25% de los problemas). Banners de cookies, barras de notificación, anuncios que se cargan después del contenido principal, widgets de chat, y elementos de retargeting que se insertan en el DOM sin espacio reservado. Cada inserción empuja el contenido existente, acumulando CLS. La solución es reservar espacio con min-height en los contenedores destinados a contenido dinámico.
3. Fuentes web que causan FOUT (15% de los problemas). Cuando una fuente personalizada tarda en cargarse y el navegador muestra primero una fuente de sistema y luego la reemplaza, las diferencias de tamaño entre ambas fuentes pueden causar reflow del texto. La directiva font-display: swap es necesaria para evitar texto invisible, pero puede contribuir al CLS si la fuente de respaldo tiene métricas muy diferentes a la definitiva. La solución es usar font-display: optional cuando las fuentes no son críticas, o aplicar size-adjust en el @font-face de la fuente de respaldo.
4. Elementos con tamaño dependiente del contenido (12% de los problemas). Componentes que calculan su altura basándose en contenido que se carga asíncronamente: carousels, tablas de precios con datos dinámicos, formularios con validación que añade mensajes de error. La solución es definir dimensiones mínimas que contengan el componente en su estado más grande.
5. Animaciones CSS que modifican propiedades de layout (8% de los problemas). Animaciones que usan top, left, width, height o margin en lugar de transform causan reflow y, si afectan a la posición de otros elementos, generan CLS. La solución es usar exclusivamente transform y opacity para animaciones, ya que estas propiedades se procesan en la GPU sin afectar el layout de otros elementos.
Cómo corregir CLS causado por imágenes sin dimensiones
Las imágenes sin dimensiones son la causa más frecuente de CLS porque el navegador, sin saber el tamaño de la imagen antes de descargarla, asigna al elemento un tamaño de 0x0 píxeles y recalcula el layout cuando la imagen finalmente carga. El shift resultante es proporcional al tamaño de la imagen: una imagen hero de pantalla completa puede generar un CLS de 0.5 por sí sola.
La solución básica es añadir atributos width y height a cada etiqueta <img>. Los navegadores modernos (Chrome 79+, Firefox 71+, Safari 14.1+) utilizan estos atributos para calcular el aspect ratio del elemento antes de descargar la imagen, reservando el espacio correcto. No es necesario que los valores coincidan con el tamaño renderizado; lo importante es que la proporción sea correcta.
<!-- Correcto: el navegador reserva espacio en proporción 16:9 -->
<img src="hero.webp" width="1600" height="900" alt="Descripción">
<!-- También correcto: CSS aspect-ratio -->
<img src="hero.webp" style="aspect-ratio: 16/9; width: 100%;" alt="Descripción">
Para imágenes responsivas con srcset, los atributos width y height deben corresponder a las dimensiones intrínsecas de la imagen más grande del conjunto. El navegador calculará el aspect ratio a partir de esos valores.
Para imágenes de fondo CSS, la técnica cambia: el contenedor debe tener aspect-ratio o un padding-bottom porcentual que reproduzca la proporción de la imagen. Un contenedor para una imagen 16:9 necesita padding-bottom: 56.25% (9/16 x 100).
Los CMSs modernos generan automáticamente width y height en las imágenes del media library, pero las imágenes insertadas manualmente en el editor, las procedentes de APIs externas o las generadas por JavaScript client-side suelen carecer de estos atributos. Auditar el HTML renderizado es imprescindible.
La diferencia de impacto es inmediata: añadir dimensiones a las cinco imágenes above the fold de un blog típico puede reducir el CLS de 0.15 a 0.02 sin ningún otro cambio. Para las imágenes below the fold, el impacto es menor pero contribuye a mantener la estabilidad durante el scroll.
Cómo corregir CLS causado por anuncios y banners dinámicos
Los anuncios programáticos son la segunda causa más frecuente de CLS y una de las más difíciles de resolver porque el tamaño del anuncio no se conoce hasta que la red publicitaria lo entrega. Un slot definido para un anuncio de 300x250 puede recibir un creativo de 300x600, duplicando la altura y empujando todo el contenido inferior.
Reservar espacio con min-height. La primera línea de defensa es definir contenedores con min-height igual al tamaño más frecuente del anuncio. Para un slot de display estándar, min-height: 250px. Para un leaderboard, min-height: 90px. Si el anuncio es más pequeño que el espacio reservado, queda un margen visual que es preferible al CLS.
Usar collapse behavior de forma intencional. Muchas redes publicitarias ofrecen la opción de colapsar el contenedor si no se sirve ningún anuncio. Si el contenedor tiene min-height y el anuncio no carga, el espacio vacío puede ser visualmente indeseable. La solución es usar un placeholder (un fondo gris sutil con texto “Publicidad” o el logo del medio) que se reemplaza por el anuncio cuando se carga.
Posicionar anuncios fuera del flujo principal. Los anuncios en posiciones sticky (fijos en la pantalla), en barras laterales con posición absoluta, o en overlays no causan CLS porque no desplazan otros elementos del flujo del documento. Mover los slots de mayor impacto a estas posiciones es la solución más radical pero también la más eficaz.
Para anuncios above the fold — los que más CLS causan porque desplazan contenido visible — la mejor práctica es cargarlos de forma síncrona con el contenido principal, no de forma diferida. Un anuncio que se carga 2 segundos después del contenido principal garantiza un layout shift visible para el usuario. Si se carga simultáneamente, el espacio se reserva desde el inicio.
CLS en mobile vs desktop: diferencias importantes
El CLS en dispositivos móviles suele ser significativamente peor que en escritorio, y las razones son estructurales:
Reflow de contenido en viewports estrechos. Un layout de tres columnas en desktop se convierte en una sola columna en móvil. Los elementos que en desktop tienen dimensiones fijas pueden expandirse verticalmente en móvil, empujando contenido de formas impredecibles. Las imágenes responsivas que cambian de aspect ratio entre breakpoints son particularmente problemáticas.
Fuentes de tamaño variable. Las fuentes web suelen renderizarse con tamaños diferentes en mobile y desktop. Si la fuente de respaldo ocupa más espacio vertical que la definitiva en un viewport estrecho, el reflow es mayor y el CLS resultante es más alto. En mobile, donde cada píxel de altura cuenta más proporcionalmente, un reflow de texto de 20px puede representar un shift significativo.
Conexiones más lentas. En conexiones 4G con latencia alta, los recursos se cargan de forma más escalonada que en fibra. Esto amplifica el CLS porque los elementos llegan en oleadas más separadas, cada una causando su propio shift. Una página que en fibra carga todos los recursos en 500ms y tiene un solo shift puede tener tres shifts separados en 4G.
Banners de cookies y barras de notificación. Estos elementos suelen inyectarse después de la carga y, en mobile, pueden ocupar el 20-30% de la altura del viewport. Si no tienen espacio reservado, el shift es proporcionalmente enorme.
La recomendación es auditar el CLS por separado en mobile y desktop, priorizando mobile porque: (a) Google utiliza el mobile-first indexing, (b) el 73% del tráfico web global procede de dispositivos móviles, y (c) los problemas de CLS son estructuralmente peores en pantallas pequeñas. Google Search Console separa los datos de Core Web Vitals por tipo de dispositivo, lo que permite identificar problemas específicos de cada plataforma.
La velocidad web y la estabilidad visual están relacionadas: las optimizaciones de rendimiento que reducen el tiempo de carga también tienden a reducir el CLS, porque los recursos llegan más rápido y se procesan de forma más homogénea. Abordar ambas métricas de forma conjunta es más eficiente que tratarlas por separado.