Back

Entendendo as Unidades de Viewport Dinâmicas em CSS

Entendendo as Unidades de Viewport Dinâmicas em CSS

Se você já construiu um layout em tela cheia em dispositivos móveis e notou que o conteúdo ficava cortado atrás da barra de endereços do navegador, você encontrou o clássico problema do 100vh. A solução costumava envolver gambiarras em JavaScript. Agora, o CSS lida com isso nativamente através de unidades de viewport modernas: svh, lvh e dvh.

Pontos-Chave

  • A unidade tradicional vh mapeia para o viewport grande em dispositivos móveis, causando overflow de conteúdo quando a barra de endereços do navegador está visível.
  • O CSS agora define três estados de viewport—grande (lvh), pequeno (svh) e dinâmico (dvh)—cada um com seu próprio conjunto de unidades.
  • Use svh para conteúdo acima da dobra, lvh para layouts imersivos em tela cheia, e dvh para designs adaptativos que respondem a mudanças na interface do navegador.
  • As unidades de viewport dinâmicas não consideram teclados virtuais; teste layouts com muitos campos de entrada em dispositivos reais.
  • Sempre inclua um fallback de vh para navegadores mais antigos que não suportam as unidades mais recentes.

Por Que vh Falha em Dispositivos Móveis

No desktop, vh funciona de forma confiável. Em dispositivos móveis, a interface do navegador—barra de endereços, abas, controles de navegação—expande e recolhe conforme os usuários rolam a página. A altura do viewport muda, mas o vh não acompanha essa mudança.

vh reflete o viewport grande (similar ao lvh), que assume que os elementos de interface do navegador estão totalmente recolhidos. Então, quando a barra de endereços está visível, um elemento com 100vh pode transbordar a área visível. O conteúdo fica cortado, botões se tornam inacessíveis e os layouts quebram.

Os Três Estados de Viewport: Grande, Pequeno e Dinâmico

A especificação CSS Values and Units define três estados distintos de viewport para resolver isso:

  • Viewport grande — medido quando toda a interface do navegador está recolhida (altura máxima disponível)
  • Viewport pequeno — medido quando toda a interface do navegador está expandida (altura mínima disponível)
  • Viewport dinâmico — rastreia qual estado está ativo no momento

Cada estado tem um conjunto correspondente de unidades CSS:

Estado do ViewportUnidade de AlturaUnidade de Largura
Grandelvhlvw
Pequenosvhsvw
Dinâmicodvhdvw

Cada família também inclui variantes min, max, inline e block (dvi, dvb, svmin, lvmax, etc.).

Importante: vh efetivamente mapeia para lvh em navegadores modernos. Ambos refletem o tamanho do viewport grande.

Em navegadores desktop sem interface dinâmica, todos os três tamanhos de viewport são idênticos.

Quando Usar svh, lvh e dvh

Use svh quando o conteúdo precisar permanecer totalmente visível no carregamento inicial da página, antes de qualquer rolagem. Isso garante que seu layout caiba dentro do menor viewport possível—com os elementos de interface do navegador totalmente visíveis.

/* Conteúdo sempre visível ao carregar, sem necessidade de rolagem */
.above-the-fold {
  min-height: 100svh;
}

Use lvh para experiências imersivas em tela cheia—jogos, telas de abertura ou shells de aplicativos—onde você quer preencher o máximo espaço disponível.

/* Preenche a tela quando os elementos de interface do navegador estão ocultos */
.fullscreen-app {
  height: 100lvh;
}

Use dvh quando você quiser que o layout se adapte conforme a interface do navegador muda. É a escolha mais prática para a maioria dos layouts responsivos.

/* Problemático em dispositivos móveis */
.hero { height: 100vh; }

/* Adapta-se às mudanças dos elementos de interface do navegador */
.hero {
  height: 100vh;   /* Fallback para navegadores mais antigos */
  height: 100dvh;  /* Navegadores modernos usam isto */
}

O padrão de fallback acima funciona porque navegadores que não reconhecem dvh vão ignorar a segunda declaração e aplicar a primeira. Navegadores modernos aplicam a última declaração válida, então 100dvh entra em vigor.

A Ressalva do Teclado Virtual

dvh lida com o redimensionamento da barra de endereços, mas não com teclados virtuais. Quando um usuário toca em um campo de entrada e o teclado na tela aparece, as unidades de viewport geralmente não se ajustam porque a maioria dos navegadores redimensiona apenas o viewport visual por padrão.

Para optar pelo comportamento de layout consciente do teclado, você pode usar a meta tag interactive-widget:

<meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content">

O valor resizes-content diz ao navegador para redimensionar o viewport quando o teclado virtual abre. Outros valores incluem resizes-visual (o padrão, que redimensiona apenas o viewport visual) e overlays-content (o teclado sobrepõe sem redimensionar nada). O suporte para esse comportamento existe atualmente principalmente em navegadores baseados em Chromium.

O Chrome também oferece controle programático através da VirtualKeyboard API. O suporte entre navegadores para essa API permanece limitado, então se seu layout depende do espaço visível abaixo de um campo de entrada, teste cuidadosamente em dispositivos reais.

Suporte dos Navegadores

svh, lvh e dvh são suportados em:

  • Chrome 108+
  • Safari 15.4+
  • Firefox 101+

A cobertura é sólida em navegadores modernos. O padrão de fallback height: 100vh mostrado acima lida com ambientes mais antigos de forma elegante. Você também pode verificar a compatibilidade atual na documentação de unidades de viewport do MDN.

Escolhendo a Unidade Certa

  • O conteúdo precisa caber no carregamento inicial?svh
  • Layout imersivo em tela cheia?lvh
  • Layout adaptativo que responde à interface do navegador?dvh
  • Suportando navegadores mais antigos? → Sempre inclua um fallback de vh

Conclusão

O problema da altura do viewport em dispositivos móveis no CSS agora tem uma solução limpa e nativa. Troque vh por dvh na maioria dos casos, use svh quando a visibilidade acima da dobra importa, e reserve lvh para experiências em tela cheia. Sempre combine as unidades mais recentes com um fallback de vh para compatibilidade retroativa, e lembre-se de que teclados virtuais requerem tratamento separado. Nenhum JavaScript necessário.

Perguntas Frequentes

Sim, mas seja cauteloso. Como dvh muda conforme a interface do navegador expande ou recolhe, um elemento fixo dimensionado com dvh pode visivelmente se mover durante a rolagem. Para cabeçalhos ou rodapés fixos com altura fixa, usar valores estáticos em pixels ou rem geralmente é mais previsível. Reserve dvh para containers de altura total em vez de pequenos elementos de tamanho fixo.

O impacto no desempenho é negligenciável para a maioria dos layouts. No entanto, se você aplicar dvh a muitos elementos profundamente aninhados que disparam recálculos complexos de layout, você pode ver pequenas travadas em dispositivos de baixo desempenho. Faça profiling em hardware real se o desempenho for crítico.

Eles seguem a mesma lógica mas se aplicam à largura do viewport. Na maioria dos navegadores móveis, a largura não muda quando a barra de endereços aparece ou desaparece, então svw, lvw e dvw normalmente retornam o mesmo valor. A distinção importa mais em dispositivos ou navegadores onde painéis laterais ou outros elementos de interface afetam a largura disponível.

Adicione interactive-widget=resizes-content à sua meta tag viewport. Isso diz ao navegador para encolher o viewport de layout quando o teclado abre, o que significa que dvh refletirá o espaço reduzido. Sem essa configuração, o teclado sobrepõe o conteúdo e as unidades de viewport permanecem inalteradas. Teste em dispositivos reais já que o comportamento varia entre navegadores e plataformas.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay