CLS: por qué tu contenido se mueve y cómo arreglarlo
CLS alto frustra usuarios y mata conversión: clickean donde no querían. Esta guía técnica explica cómo identificar y eliminar layout shifts.
El CLS (Cumulative Layout Shift) es la métrica de Google que mide cuánto se mueve el contenido visible mientras tu sitio carga. Si tu CLS está mal, el usuario ve un botón, intenta tocarlo, y justo en ese momento aparece un banner que mueve TODO 60 píxeles hacia abajo. Resultado: tap accidental en un anuncio o en otro link. Frustración pura. Conversión perdida.
Qué mide CLS
A diferencia de LCP e INP que se miden en milisegundos, CLS es un número sin unidad que representa la suma de cuánto y cuán violentamente se movió tu contenido. Cuanto más alto, peor.
Zonas oficiales:
- Bueno: menos de 0.1
- A mejorar: entre 0.1 y 0.25
- Pobre: más de 0.25
Verificá el CLS actual de tu sitio en nuestro test de velocidad.
Por qué CLS importa tanto para conversión
Más que cualquier otra métrica, CLS impacta directo en la tasa de error de los usuarios:
- Hacen click en un banner sin querer
- Pierden el lugar donde estaban leyendo
- Tocan "Cancelar" cuando querían "Confirmar"
- Se cierra un modal porque tap accidental
Sumado al estrés visual: aumenta la tasa de rebote. La gente cierra el tab y se va.
Las 6 causas más comunes de CLS alto
1. Imágenes sin dimensiones declaradas
El error #1 históricamente. Si tu HTML tiene:
<img src="/hero.jpg">
El navegador reserva 0 espacio hasta que la imagen carga. Cuando carga, "empuja" todo lo que está debajo. CLS al cielo.
Solución: siempre declará width y height (o aspect-ratio en CSS):
<img src="/hero.jpg" width="1200" height="600" alt="...">
Los navegadores modernos usan width/height para calcular el aspect-ratio incluso si después el CSS redimensiona la imagen.
2. Iframes sin tamaño
Embeds de YouTube, Twitter, Instagram, Google Maps. Cada uno carga asíncrono y sin width/height reservados causan shifts. Solución idéntica: declarar dimensiones o usar contenedor con aspect-ratio:
.video-wrap {
aspect-ratio: 16 / 9;
width: 100%;
}
.video-wrap iframe {
width: 100%;
height: 100%;
}
3. Fuentes web que cambian de tamaño (FOUT/FOIT)
Cuando tu fuente custom carga, el texto que se mostraba con la fuente fallback se "reflowa" al tamaño nuevo. Cada vez que veas contenido text-based moviéndose en la carga, casi siempre es esto.
Soluciones:
- Preload de la fuente crítica
- Usá
font-display: optionalsi no es crítica - Auto-host las fuentes (Google Fonts desde CDN suma latencia)
- Si el problema es cambio de tamaño visual: usá size-adjust y ascent-override para que la fallback ocupe el mismo espacio que la final
4. Banners de cookies, popups y CTAs inyectados
El banner de cookies que aparece DESPUÉS de cargar la página y empuja contenido = CLS alto. Soluciones:
- Reservá el espacio del banner desde el primer paint
- Mostralo como overlay (fixed/absolute), no como bloque que empuja
- Si tiene que ser bloque, ponelo en el HTML inicial (no inyectado por JS después)
5. Anuncios y widgets de terceros
AdSense, banners de afiliados, widgets de Twitter, embeds de Spotify. Suelen cargar después y cambian el layout.
- Reservá el contenedor con dimensiones mínimas (
min-height) - Si el ad no llena el espacio, dejalo vacío (mejor que un shift)
- Posicioná abajo del fold cuando puedas
6. Lazy loaded content sin placeholder
Imágenes lazy-loaded sin reservar espacio, scroll-triggered animations que aparecen "desde la nada", contenido AJAX que se inyecta en medio del viewport.
Solución: siempre placeholder con altura conocida (skeleton, blurhash, color sólido).
Casos especiales que vemos seguido
WooCommerce / Shopify
Los catálogos de productos a veces tienen layouts que cambian cuando se carga el precio o el stock. Reservá ese espacio con CSS desde el HTML inicial.
Blogs con imágenes
El error clásico: pegar imágenes desde el editor sin width/height. Si tu CMS no las agrega automáticamente, usá un plugin que lo haga (en WordPress: WP Image Lazy Loading + dimensiones automáticas).
Sliders y carruseles
Los carruseles que cambian de altura entre slides causan CLS al rotar. Solución: forzá altura uniforme con min-height en el contenedor.
Checklist de optimización CLS
- Width y height declarados en TODAS las imágenes
- Aspect-ratio en iframes y videos
- Preload +
font-display: swapen fuentes críticas - Banner de cookies como overlay o pre-reservado
- Min-height en contenedores de ads
- Placeholders en lazy loaded content
- Sin inyección de contenido above-the-fold después del initial render
- Auditá con DevTools → Performance → Experience (te muestra cada shift)
Cómo identificar shifts específicos
En Chrome DevTools:
- Abrí DevTools → Performance
- Grabá un reload
- Mirá la fila "Experience" en el timeline
- Cada bloque rojo = un shift. Click te muestra qué elemento se movió y por qué
En PSI también marca elementos con CLS visible bajo "Diagnostics".
Cuando es invisible pero alto
A veces el CLS está alto pero "vos no notás nada". Es porque el shift sucede después de que ya leíste el contenido. PERO Google lo ve. Las causas típicas:
- Contenido que carga al hacer scroll (lazy) y empuja
- Comentarios que se cargan tarde y empujan el footer
- Sidebar con widgets que se "estiran"
Estos casos son los más difíciles de diagnosticar. La extensión Web Vitals de Chrome los muestra en tiempo real.
CLS bajo es un sello de profesionalismo. Cuando un sitio NO se mueve mientras carga, el usuario lo siente "sólido" sin saber por qué.
Mantenimiento continuo
El CLS se rompe fácil: sumás un widget nuevo, instalás un plugin, cambiás un banner. Por eso conviene monitoreo continuo:
- Search Console → Core Web Vitals: te avisa si una página entra en rojo
- Tests mensuales con nuestra tool
- Si tenés plan de mantenimiento con nosotros, lo monitoreamos automáticamente
Próximos pasos
- Si LCP también te falla: leé cómo bajar el LCP de tu sitio
- Si tu sitio se siente trabado al click: cómo mejorar INP
- Para una auditoría completa con plan de acción: hacemos SEO técnico profesional