Blog

Blog

Como otimizar CLS - Guia Core Web Vitals

CLS (Cumulative Layout Shift) mede o deslocamento visual dos elementos da página depois que eles aparecem na tela, e o Google considera bom qualquer valor abaixo de 0,1 em field data. Apesar de ser a métrica do Core Web Vitals com a maior taxa de aprovação global (em torno de 80% dos sites móveis estão na faixa "Bom", segundo o Web Almanac 2024 do HTTP Archive), ainda é uma das mais traiçoeiras de diagnosticar. O pico de CLS de um site costuma estar concentrado em momentos específicos da sessão: o aparecimento do banner de cookies, a substituição da fonte fallback pela fonte web ou o carregamento tardio de um embed. Este artigo explica como o navegador calcula a métrica, detalha as cinco causas que respondem por 90% dos casos e mostra correções modernas que resolvem a maior parte deles.

Para o panorama completo das três métricas do Core Web Vitals, veja antes Como medir, diagnosticar e otimizar Core Web Vitals. Para as as outras métricas do CWV, Como otimizar LCP e Como otimizar INP.

O que CLS mede e como o número é calculado

CLS não é quantas vezes a página "mudou de lugar", é uma soma ponderada de deslocamentos individuais, agrupada em janelas de sessão. A especificação Layout Instability da W3C define que cada deslocamento recebe uma pontuação calculada como fração de impacto × fração de distância: a primeira mede quanto da viewport foi afetada pelo deslocamento; a segunda mede quanto da maior dimensão da viewport o conteúdo se moveu. O valor final reportado é o pior somatório dentro de uma janela móvel de 5 segundos, com gap de 1 segundo entre deslocamentos, conforme atualização do Chrome Speed Metrics Team em 2021.

Diagrama mostrando um banner sendo injetado no topo da página e empurrando o conteúdo 100px para baixo. Ao lado, a fórmula CLS = impact × distance, com exemplo numérico de 0,031.

Os limites oficiais aplicados pelo Google são os seguintes:

StatusValor de CLS
Bomaté 0,1
Precisa de melhorias0,1 a 0,25
Ruimacima de 0,25

Há uma exclusão crítica no cálculo: shifts que ocorrem nos 500 milissegundos seguintes a uma interação do usuário não contam. Abrir um menu accordion, expandir um filtro ou clicar em "ler mais" são ações que o navegador entende como "movimento esperado pelo usuário". O que entra na conta de CLS são os deslocamentos involuntários, que acontecem sem que o usuário tenha provocado, geralmente porque algum elemento da página demorou para carregar.

As cinco causas que respondem por 90% dos casos

Imagens sem width e height declarados. Quando uma tag <img> carrega sem atributos de dimensão, o navegador não reserva espaço para ela no fluxo do documento. O texto e demais elementos renderizam ocupando o lugar onde a imagem deveria estar, e quando o arquivo finalmente é baixado, tudo é empurrado para baixo. A correção é trivial: declarar width e height no HTML, mesmo para imagens responsivas, mas continua sendo uma das causas mais comuns de CLS justamente por parecer pequena demais para virar prioridade durante o desenvolvimento.

Fontes web com swap de fallback. Quando a fonte personalizada do site é baixada e substitui a fonte de fallback do sistema, o texto frequentemente muda de tamanho, kerning ou altura de linha. Isso desloca todo o conteúdo abaixo. Em sites que carregam três ou quatro variações de uma família de fonte (regular, bold, italic, light), o efeito se multiplica. A correção é combinar font-display: swap com as propriedades size-adjust, ascent-override e descent-override no @font-face, que alinham as métricas do fallback com a fonte final.

Banners de cookie e notificações injetadas no topo. Esta é a causa número um de CLS em sites brasileiros e europeus, por força regulatória da LGPD e do GDPR. O banner aparece de 1 a 3 segundos após o load, ou seja, fora da janela de 500ms da interação do usuário, e empurra todo o conteúdo da tela para baixo. Quando o banner usa altura variável (porque o texto se ajusta por idioma ou país), o problema piora.

Anúncios e embeds sem dimensões definidas. Slots de Adsense, iframes de YouTube e Vimeo, widgets do Instagram e botões de redes sociais geralmente chegam tarde no carregamento e podem ter altura imprevisível. Sem dimensões reservadas, cada um desses elementos é um candidato a gerar CLS. Para anúncios, o problema é especialmente difícil porque a altura do bloco depende do criativo que o servidor de mídia vai entregar.

Animações que afetam o layout. Animar propriedades como width, height, top, left ou margin força o navegador a recalcular layout e qualquer recálculo de layout que aconteça fora da janela de 500ms da interação conta como CLS. A correção é usar exclusivamente transform e opacity, em animações decorativas, que são processadas sem afetar o layout dos elementos vizinhos.

Como medir CLS corretamente

A divergência entre lab data e field data é maior no CLS do que nas outras métricas do Core Web Vitals. PageSpeed Insights mostra um CLS lab medido em ambiente sintético, sem cookies aceitos, sem interação e sem scroll enquanto o CLS real do usuário inclui tudo isso. É comum um site pontuar pior no Search Console do que no Lighthouse justamente porque o banner de cookies, o scroll e a abertura de menus simplesmente não existem no teste de laboratório.

Para diagnóstico granular, há três opções:

  1. Extensão CLS Visualizer do Chrome. Destaca o deslocamento exato de cada elemento enquanto você navega o site. É a forma mais rápida de identificar visualmente o que desloca.
  2. Performance panel do Chrome DevTools, lane "Layout Shifts". Grava uma sessão completa e mostra cada shift como uma barra roxa, com timestamp e elementos envolvidos. Permite reproduzir o cenário exato de uma sessão problemática.
  3. Performance Observer API com entries layout-shift. Coletadas em RUM próprio e enviadas para o seu analytics, permitem ranquear quais elementos desloca mais por template, por device, por país. A biblioteca web-vitals faz a coleta automaticamente, lidando inclusive com a complexidade de medir CLS em abas que ficam abertas por horas.

As correções modernas que resolvem 80% dos casos

aspect-ratio no CSS

Suportada em todos os navegadores modernos desde 2021, a propriedade aspect-ratio permite reservar o espaço de um elemento em proporção definida, independentemente do tamanho final renderizado. Para imagens responsivas, a combinação aspect-ratio: 16 / 9; width: 100%; faz o navegador alocar exatamente a altura correta antes que o recurso termine de baixar, eliminando o shift no carregamento. Vale para imagens, vídeos, embeds e qualquer elemento com proporção previsível, e funciona em combinação com <picture> e srcset para imagens responsivas.

content-visibility: auto com contain-intrinsic-size

Para listas longas, comentários infinitos e conteúdo abaixo da dobra, a propriedade content-visibility: auto instrui o navegador a pular o render do elemento até que ele entre na viewport. Isso reduz drasticamente o trabalho de pintura no carregamento. O problema é que, sem dimensão declarada, o navegador assume altura zero para o elemento oculto e quando o conteúdo é finalmente renderizado, ocorre deslocamento. A combinação correta usa contain-intrinsic-size para reservar uma altura estimada: content-visibility: auto; contain-intrinsic-size: auto 500px;. O navegador economiza o render sem causar CLS.

View Transitions API

Estável no Chrome desde a versão 111 (2023) e no Safari 18+ desde o final de 2024. A API permite animar a transição entre dois estados da página: mostrar/ocultar elementos, abrir/fechar modais ou navegar entre páginas. View Transitions não reduz CLS calculado, mas torna invisível o shift quando ele ocorre, tornando o que seria um pulo abrupto em uma animação suave de frações de segundo. É menos uma correção e mais uma "maquiagem" útil quando o shift não pode ser eliminado.

Otimização de fontes web

Há três tratamentos possíveis, por ordem de impacto: primeiro, reduzir o número de famílias e pesos carregados (cada arquivo de fonte é uma requisição); segundo, usar font-display: swap para evitar texto invisível enquanto a fonte carrega; terceiro, alinhar as métricas do fallback usando size-adjust, ascent-override e descent-override no @font-face. A ferramenta Fontaine calcula automaticamente esses valores para uma combinação fonte/fallback específica, e existem integrações prontas para Next.js, Nuxt e Astro.

O caso específico do banner de cookies (LGPD/GDPR)

O banner de cookies é tema separado porque concentra o pior cenário possível para CLS: elemento de altura variável, injetado após o load, fora da janela de interação. Há três opções para lidar com esse problema:

  1. Posicionar com position: fixed no fundo da viewport. Não desloca nenhum conteúdo da página. A maioria dos consultores de privacidade aceita essa configuração, desde que o banner seja claramente visível. É a solução com menor custo de CLS e maior chance de aprovação jurídica.
  2. Reservar espaço no topo desde o início. Adicionar um min-height ao container do banner equivalente à altura média esperada, mesmo enquanto o conteúdo do banner ainda não chegou. Quando o usuário aceita ou recusa, o espaço fica vazio até o próximo render, o que é aceitável visualmente e zera CLS.
  3. Acionar o banner apenas após interação do usuário. O banner aparece quando o usuário clica em um botão "Configurações de privacidade" no header. Shifts dentro de 500ms de uma interação não contam para CLS. Funciona em jurisdições que permitem o "consentimento implícito por navegação" até o usuário escolher.

A situação a evitar, e que é muito comum em sites brasileiros, é um banner no topo, com altura variável, 2 segundos após o load. É o cenário que mais penaliza o CLS.

O que mudou em CLS entre 2024 e 2026

2024. A propriedade aspect-ratio consolidou-se como padrão de mercado: frameworks como Next.js, Astro e Nuxt passaram a aplicá-la por default em componentes de imagem. A integração da biblioteca Fontaine com Next.js automatizou a otimização de fontes em uma das stacks mais populares.

Final de 2024 e 2025. Cross-document View Transitions chegou ao Safari 18.2, tornando a API utilizável em sites e aplicações com múltiplas páginas (MPAs) com cobertura ampla de navegadores modernos. O Search Console passou a exibir, no relatório de Core Web Vitals, quais elementos da página individualmente contribuíram para o CLS, o que facilitou o diagnóstico em sites grandes.

2026. A taxa global de aprovação em CLS continuou subindo. O Web Almanac 2025 reporta 48% dos sites móveis e 56% dos desktops com Core Web Vitals "Bom" em todas as três métricas, e a melhoria mais consistente ao longo dos anos veio justamente do CLS, que evoluiu de 74% para cerca de 80% de aprovação entre 2022 e 2024 graças ao uso disseminado de dimensões declaradas e aspect-ratio.

Como monitorar CLS

CLS é a métrica mais regressiva das três: qualquer alteração de layout, novo plugin, nova fonte ou banner adicional pode gerar shift onde antes não havia. Monitoramento mensal via Search Console é essencial. Para times com volume suficiente de tráfego que gere field data no CrUX, três práticas são recomendadas:

  1. Alerta automático em RUM. Se o p75 de CLS de qualquer template exceder 0,1 em três dias consecutivos, ticket no backlog. Regressões de CLS quase sempre são causadas por mudança recente identificável em changelog.
  2. Auditoria pré-launch para banners e overlays. Toda nova notificação, modal, exit popup ou cookie banner deve passar por validação no Performance panel do DevTools e ser aprovado por critério de CLS antes de ir para produção.
  3. Documentação de evolução por template. O CLS varia muito entre uma homepage e uma página de produto, por exemplo. Acompanhar separadamente cada template, e não só a média do domínio, é o que permite identificar a regressão antes que ela contamine o relatório global.

Estudos de caso publicados pelo Google reforçam o impacto comercial direto: o Telegraph reduziu o p75 de CLS de 0,25 para 0,1 e aumentou a faixa "Bom" de 57% para 72%; o Yahoo! JAPAN News aumentou em 15% as páginas visualizadas por sessão após corrigir os principais deslocamentos de conteúdo no carregamento. Em ambos os casos, a correção principal foi reservar espaço para elementos que demoram para carregar, sem precisar de outras otimizações.

Perguntas frequentes sobre CLS

Layout shift causado por scroll do usuário conta para CLS?

Não. Shifts que ocorrem dentro de 500 milissegundos após qualquer interação do usuário, como cliques, toques, scrolls e teclas, são excluídos do cálculo. Apenas deslocamentos involuntários, ou seja, aqueles que acontecem sem ação prévia do visitante, entram na conta da métrica.

Posso animar height em vez de transform quando a animação é disparada por clique?

Sim, com a ressalva da janela de 500ms. Animações ativadas por interação do usuário, como abrir um accordion, expandir um card, mostrar/ocultar um filtro, não contam para CLS desde que a mudança ocorra nos primeiros 500ms após o clique. Animações de duração maior, ou animações disparadas por timer e por scroll, contam.

Imagens com loading="lazy" causam CLS?

Se não tiverem width e height declarados, sim. O atributo loading="lazy" por si só não introduz CLS, o que introduz é a ausência de dimensão reservada. Imagens lazy-loaded com width, height e aspect-ratio corretos são seguras e fortemente recomendadas para conteúdo abaixo da dobra.

Como meço CLS de um popup de saída (exit-intent)?

Popups de exit-intent são acionados por movimento do mouse do usuário em direção a fechar a aba, e portanto entram na janela de 500ms da interação e não contam para CLS. Popups acionados por temporizador (após X segundos) contam. Para popups modais centralizados sobre overlay, o CLS é mínimo mesmo sem exclusão, porque o overlay cobre conteúdo sem deslocá-lo.

CLS pesa tanto quanto LCP e INP para ranqueamento?

Sim, as três métricas têm o mesmo status como sinal de experiência de página dentro do Core Web Vitals e a aprovação no conjunto exige passar nas três simultaneamente em field data. CLS costuma ser o problema menos persistente em sites bem otimizados, porque a correção é pontual e raramente regride por motivos sistêmicos. LCP e INP costumam ser os gargalos crônicos.

Vale a pena adotar View Transitions só para esconder CLS?

Não como estratégia principal. View Transitions API mascara o shift visualmente, mas o número que o Search Console reporta continua o mesmo e o shift ainda é medido. A API é útil quando o shift não pode ser eliminado por restrições de produto (conteúdo dinâmico, dimensões variáveis), e o objetivo é apenas reduzir o impacto percebido pelo usuário. Como correção real, sempre prefira reservar espaço com aspect-ratio ou contain-intrinsic-size.


Para validar se sua página atende ao critério de CLS e aos outros 60+ critérios técnicos de SEO, use o SEO Check. Para entender como sua performance se compara com a média da web e com o top 1000 dos sites mais populares, SEO Benchmark.

Continue lendo

SEO Técnico Análise de SEO: o que verificar e como fazer um diagnóstico 12 min de leitura SEO Técnico Como otimizar INP - Guia Core Web Vitals 16 min de leitura