--:--:--

z-index não funciona: como diagnosticar stacking context, overflow e top layer no CSS

Publicado em 2026-08-29T20:14:00Z · atualizado em 2026-08-29T19:14:11+00:00

Você define `z-index: 999999` no modal e ele continua atrás do cabeçalho. O número não está sendo ignorado: ele está sendo comparado apenas dentro de um **stacking context**. Um filho não escapa do contexto do pai, ainda que receba um valor

Hierarquia de stacking contexts com elementos filhos limitados pelo contexto pai
Imagem de apoio ao tema do artigo.

z-index não funciona: como diagnosticar stacking context, overflow e top layer no CSS

Você define z-index: 999999 no modal e ele continua atrás do cabeçalho. O número não está sendo ignorado: ele está sendo comparado apenas dentro de um stacking context. Um filho não escapa do contexto do pai, ainda que receba um valor enorme. transform, opacity, filter, contain, itens flex/grid e outros recursos podem criar novas pilhas.

Este guia ensina a reproduzir o problema, inspecionar ancestrais, diferenciar ordem de empilhamento de recorte por overflow, usar portais e top layer e construir uma escala de camadas previsível.

Hierarquia de stacking contexts com elementos filhos limitados pelo contexto pai Legenda: valores dos filhos só competem dentro do contexto ao qual pertencem.

z-index compara elementos no mesmo contexto

A MDN descreve contextos como unidades independentes. Depois de ordenar seus descendentes, o navegador trata o contexto inteiro como uma peça no pai.

<div class="painel"><div class="modal">Modal</div></div>
<header>Cabeçalho</header>
.painel { position: relative; z-index: 1; }
.modal { position: absolute; z-index: 9999; }
header { position: relative; z-index: 2; }

O modal perde porque painel inteiro está na camada 1, abaixo do header 2.

Laboratório reproduzível

Salve HTML completo:

<!doctype html>
<style>
  .a { position: relative; z-index: 1; background:#def; padding:40px; }
  .modal { position:absolute; z-index:9999; top:20px; left:20px; background:#fff; border:3px solid purple; }
  .b { position:relative; z-index:2; margin-top:-20px; background:#faa; padding:50px; }
</style>
<div class="a">Contexto A <div class="modal">z-index 9999</div></div>
<div class="b">Contexto B — z-index 2</div>

Remova z-index:1 de .a e observe. O experimento prova que o ancestral, não o número do modal, decide a disputa externa.

Propriedades que criam stacking context

Entre as causas comuns:

  • raiz do documento;
  • position: relative/absolute com z-index não automático;
  • position: fixed ou sticky;
  • item flex ou grid com z-index;
  • opacity menor que 1;
  • transform, filter, perspective ou clip-path;
  • isolation: isolate;
  • contain: layout ou paint;
  • will-change para propriedade que criaria contexto;
  • elementos na top layer.

Não remova propriedades aleatoriamente. No DevTools, caminhe pelos ancestrais e desative uma candidata por vez.

position ainda importa

Historicamente, z-index é associado a elementos posicionados. A propriedade define ordem de elementos posicionados e também itens flex/grid. Um div comum com position: static pode não responder como esperado.

.tooltip {
  position: absolute;
  z-index: 20;
}

Mas adicionar position: relative a muitos ancestrais com z-index pode criar mais contextos. Posicione somente onde há necessidade de referência ou empilhamento.

transform no ancestral é um suspeito frequente

.card { transform: translateZ(0); }

Esse truque de desempenho cria contexto. Um tooltip dentro da card pode ficar atrás de outra card. Remova se não for necessário ou renderize o overlay em ancestral apropriado.

Transform também muda o bloco de referência de descendentes fixed em certos casos. Um modal position: fixed dentro de ancestral transformado pode se comportar como preso ao componente.

opacity, filter e animação

opacity: .99, filter: drop-shadow(...) e animações com preenchimento podem criar contextos sem nenhum z-index visível. Inspecione estilos computados, não apenas a regra do componente.

Evite usar opacity no contêiner para desbotar tudo quando precisa apenas de fundo translúcido. Use cor com alfa:

.overlay { background: rgb(0 0 0 / .5); }

Assim os filhos não ficam transparentes e você reduz contexto acidental.

overflow recorta; z-index não desrecorta

Um menu pode estar acima na pilha e ainda desaparecer porque um ancestral possui overflow: hidden, clip ou auto. z-index não permite desenhar fora da área de recorte.

.card { overflow: hidden; border-radius: 16px; }
.menu { position: absolute; z-index: 100; }

Soluções: mover o menu para fora do ancestral, usar portal, redesenhar o recorte ou avaliar APIs de popover. Não transforme todo overflow em visible; isso pode quebrar rolagem e cantos.

Diferença entre ordem de empilhamento e recorte por overflow Legenda: um elemento pode estar no topo de sua pilha e ainda ser cortado pela caixa ancestral.

Flex e grid surpreendem

Itens flex e grid podem aceitar z-index e criar contexto mesmo sem position. Verifique o item, não apenas o overlay interno.

.layout { display:grid; }
.sidebar { z-index:2; }
.main { z-index:1; }

Um dropdown dentro de .main não ultrapassa .sidebar se o contexto da main está abaixo. Ajuste a relação entre os itens irmãos ou mova o overlay.

Ordem do HTML em valores iguais

Sem z-index, elementos posicionados no mesmo nível seguem regras de pintura e ordem do documento. Com valores iguais, a ordem posterior costuma aparecer acima na mesma categoria.

Não dependa de reordenar HTML apenas para corrigir modal. A ordem semântica afeta leitura, foco e acessibilidade. Defina arquitetura de camadas.

Valores negativos

z-index:-1 pode colocar o elemento atrás do fundo do contexto e fazê-lo parecer sumir. É útil em efeitos controlados, mas difícil em componentes aninhados.

Prefira pseudo-elemento dentro de contexto isolado:

.botao { position:relative; isolation:isolate; }
.botao::before { content:""; position:absolute; inset:0; z-index:-1; }

Teste foco e clique, pois uma camada visual pode interceptar eventos.

pointer-events não muda empilhamento

Um elemento transparente por cima pode bloquear cliques. Use DevTools para identificar o elemento sob o cursor. pointer-events:none permite atravessar, mas não o torna visualmente inferior.

Não aplique ao modal inteiro; botões deixariam de funcionar. Use somente na camada decorativa que não precisa interação.

Portais para overlays

Frameworks podem renderizar modal, tooltip e menu em um nó próximo ao body, fora de contextos do componente. A posição visual continua relacionada ao gatilho por coordenadas.

<body>
  <div id="app"></div>
  <div id="overlays"></div>
</body>

Portais exigem gerenciamento de foco, fechamento por Escape, clique externo, rolagem e leitura por tecnologia assistiva. Não são apenas correção visual.

Top layer, dialog e popover

Elementos exibidos na top layer, como dialog.showModal() e popovers, ficam em camada especial acima dos contextos comuns. Isso evita guerras de números.

<dialog id="confirmar"><p>Confirmar ação?</p><button>Fechar</button></dialog>
<script>confirmar.showModal();</script>

Use a API semanticamente adequada, implemente rótulo e foco e teste compatibilidade exigida. O ::backdrop permite estilizar o fundo.

Uma escala de camadas pequena

:root {
  --z-base: 0;
  --z-sticky: 10;
  --z-menu: 20;
  --z-overlay: 30;
  --z-toast: 40;
}

A escala documenta papéis, mas não atravessa contextos. Evite valores 999999 distribuídos. Componentes internos podem usar escala local, enquanto overlays globais vivem em raiz comum.

Diagnóstico no DevTools

  1. selecione o elemento coberto;
  2. confirme position e z-index computados;
  3. suba ancestrais procurando criadores de contexto;
  4. identifique o elemento que aparece acima;
  5. encontre o ancestral irmão comparável;
  6. teste desativando uma propriedade;
  7. verifique overflow e clipping;
  8. valide em viewport móvel.

Alguns navegadores oferecem visualização de camadas. Use como evidência, mas mantenha um caso mínimo reproduzível.

Modal atrás de header: correção estrutural

Em vez de aumentar o modal dentro de <main>, renderize o overlay em #overlays irmão do header, ou use dialog. Defina header em camada sticky e overlay acima na mesma raiz.

Também bloqueie rolagem com cuidado, preserve posição e restaure foco ao gatilho. Uma solução visual sem acessibilidade permanece incompleta.

Testes de regressão visual

Crie casos com header sticky, card transformada, contêiner com overflow, zoom e mobile. Capture screenshot automatizada ou valide relações com ferramentas do navegador.

Teste clique e teclado, não apenas pixels. O overlay deve aparecer, receber foco, não ser recortado e fechar corretamente.

Use o criador de fluxogramas, as ferramentas e a biblioteca para documentar hierarquia e testes.

Checklist final

Antes de editar, desenhe a árvore de contextos, não apenas a DOM. Para cada ancestral, anote qual propriedade cria contexto e com qual valor ele compete entre irmãos. Isso explica por que um filho 9999 fica abaixo de um contexto 2.

Componentes reutilizáveis não devem impor camada global sem contrato. Uma card pode usar z-index local para decoração, mas não deveria disputar com o modal do aplicativo. isolation:isolate pode conter deliberadamente uma pilha quando essa fronteira está documentada.

Portais resolvem o contexto, porém exigem posicionamento, rolagem, redimensionamento e limites da viewport. Um menu ancorado precisa acompanhar seu botão e continuar visível quando o conteúdo muda. Teste zoom e tradução.

Cabeçalhos sticky criam casos que aparecem somente depois da rolagem. Verifique o overlay antes, durante e após o ponto de aderência. Um ancestral com overflow também pode impedir sticky, mesmo quando a ordem parece correta.

Bibliotecas de animação adicionam transform ou opacity temporariamente. O defeito pode ocorrer apenas durante a transição. Pause animações no DevTools e compare estilos antes, durante e depois.

Sombras podem ser recortadas embora o conteúdo esteja corretamente empilhado. Diferencie recorte visual de sobreposição. Um wrapper externo pode preservar cantos arredondados e permitir o menu fora da área cortada.

Pseudo-elementos participam da pilha e podem cobrir controles. Camadas decorativas podem usar pointer-events:none, mas foco, contraste e clique precisam ser testados no elemento real.

Top layer também precisa de política. Dois diálogos modais simultâneos confundem foco. Mantenha fila ou substituição, rotule cada diálogo e devolva foco ao gatilho.

Use conteúdo longo, zoom de 200%, teclado, toque e viewport estreita. Uma captura bonita não prova que o overlay recebe foco, evita recorte e fecha corretamente.

Registre quais componentes usam top layer, portal ou camada local. Com arquitetura explícita, novos recursos não recomeçam a corrida de números mágicos.

Quando remover transform ou contain, meça desempenho e layout. Se a propriedade é necessária, mover o overlay costuma ser mais seguro que combater o contexto.

Revise ainda os estados de foco, hover, active e disabled. Alguns componentes alteram transform, opacity ou filtros apenas nesses momentos e criam um contexto temporário. O overlay pode funcionar parado e falhar exatamente durante a interação.

Teste a ordem após hidratação e carregamento tardio de estilos. CSS de terceiros inserido depois pode mudar position, overflow ou z-index. Defina escopo e ordem de folhas, evite seletores globais e registre a propriedade computada no momento da falha.

Por fim, valide impressão e modo de alto contraste quando fizer sentido. Overlays podem precisar desaparecer na impressão, enquanto conteúdo essencial deve permanecer acessível sem depender apenas da camada visual.

Crie uma página de laboratório com todos os overlays do sistema: dropdown, tooltip, cabeçalho, modal, toast e popover. Faça-os coexistir e registre a ordem esperada. Essa página vira referência visual e reduz correções locais contraditórias.

Uma escala global deve expressar categorias, não componentes individuais. Se cada tela adiciona --z-modal-clientes, --z-modal-produtos e valores novos, a arquitetura voltou à competição numérica. Modais pertencem à mesma camada e sua ordem deve ser controlada pela pilha de abertura.

Conteúdo dentro de iframe possui outro documento e outra pilha. Um filho não pode desenhar fora da caixa do iframe. Para menus ou diálogos globais, coordene com a página pai por interface autorizada e renderize o overlay no documento correto.

Elementos em fullscreen e top layer seguem regras próprias. Teste o componente quando a página entra em tela cheia; um overlay comum pode ficar abaixo. Use APIs apropriadas e trate eventos de entrada e saída.

position: fixed não garante topo absoluto. Além de contextos, ancestrais transformados podem alterar seu comportamento. Mova o fixed para uma raiz de overlays ou remova o ancestral criador apenas se isso não comprometer a animação.

No DevTools, observe também clip-path, mask, backdrop-filter, mix-blend-mode, will-change e container-type. Propriedades adicionadas por tema ou utilitário podem ser a causa mesmo ausentes no arquivo do componente.

Ao terminar, reduza o caso mínimo e escreva um comentário arquitetural, não uma narrativa do bug. Exemplo: “overlays globais são renderizados em #overlays; componentes não devem criar z-index acima de menu”. Uma regra verificável evita regressão melhor que “não mexer neste 9999”.

  • elementos comparados pertencem ao mesmo contexto;
  • ancestrais com transform, opacity, filter e contain foram inspecionados;
  • position e z-index computados estão corretos;
  • overflow e clipping foram diferenciados de empilhamento;
  • flex e grid foram considerados;
  • valores negativos não esconderam conteúdo;
  • pointer-events não foi confundido com ordem visual;
  • overlays globais usam portal ou top layer quando adequado;
  • escala de camadas é pequena e sem números mágicos;
  • foco, teclado, rolagem e mobile foram testados;
  • existe caso mínimo e teste de regressão.

Documentação primária

Nota de produção

Rascunho autoral orientado à busca “z-index não funciona”. Os exemplos são mínimos e independentes de framework. A revisão humana deve abrir o laboratório nos navegadores suportados, validar acessibilidade e revisar os links antes da publicação.

Camada extra: como tomar uma decisão melhor neste cenário

Em uso real, z-index não funciona: como diagnosticar stacking context, overflow e top layer no CSS costuma envolver mais de uma camada. O ganho de qualidade aparece quando cada camada tem uma pergunta de verificação antes de qualquer mudança definitiva.

Você define `z-index: 999999` no modal e ele continua atrás do cabeçalho. O número não está sendo ignorado: ele está sendo comparado apenas dentro de um **stacking context**. Um filho não escapa do contexto do pai, ainda que receba um valor A ideia central pode ser testada com quatro perguntas: o que foi observado, qual hipótese explica o sintoma, qual mudança é reversível e qual evidência prova que funcionou. Esse encadeamento evita que uma coincidência seja confundida com causa e torna o procedimento repetível por outra pessoa.

Qualidade de IA precisa de um teste, não de uma impressão

Para CSS, z-index, stacking context, frontend, escolha três tarefas representativas: uma simples, uma ambígua e uma em que a resposta possa ser conferida em fonte primária. Compare utilidade, rastreabilidade, privacidade, velocidade e quantidade de correção humana necessária. Uma resposta elegante não compensa uma citação inexistente ou uma conclusão que não pode ser reproduzida.

Separe ainda o que pode sair do dispositivo do que deve permanecer local. Dados públicos toleram fluxos diferentes de documentos internos, contratos, informações pessoais ou bases de clientes. A escolha entre processamento local e nuvem deve ser feita pelo risco do conteúdo, não apenas pela conveniência da interface.

Grade de avaliação prática

CritérioPerguntaEvidência
CorreçãoA resposta bate com a fonte?Checagem independente
RastreabilidadeÉ possível localizar de onde veio?Citação ou trecho verificável
PrivacidadeQue dado sai do dispositivo?Política e configuração
EsforçoQuanto trabalho humano resta?Tempo de revisão

O ponto em que a IA deixa de ajudar

Se a tarefa exige precisão absoluta e a saída não pode ser validada, a automação deve ser limitada a apoio: localizar trechos, organizar opções ou preparar uma primeira versão. A decisão final precisa permanecer com alguém capaz de verificar a fonte e assumir a responsabilidade pelo resultado.

Checklist de fechamento

  • Registre o estado inicial antes de alterar qualquer coisa.
  • Faça uma mudança por rodada e anote o efeito.
  • Teste um caso normal, um caso-limite e o cenário que originalmente falhou.
  • Confirme que a solução continua válida depois de reiniciar, reabrir ou repetir o fluxo.
  • Guarde uma forma de voltar ao estado anterior quando a alteração for destrutiva.

Esse método acrescenta profundidade sem transformar o artigo em teoria abstrata: o leitor entende por que cada passo existe e como reconhecer quando a situação exige uma decisão diferente.

#CSS #z-index #stacking context #frontend #acessibilidade