Curso de CSS / z-index e contextos de empilhamento
O z-index controla a sobreposição dentro do contexto de empilhamento relevante, em vez de atribuir a cada elemento uma profundidade global. Um filho com um z-index alto pode permanecer atrás de um elemento em um contexto de ancestral mais elevado, e o z-index não pode desfazer o recorte por overflow.
Separe o posicionamento da ordem de empilhamento
Para comparar a ordem de sobreposição, os dois elementos devem realmente ocupar a mesma área da tela. Se eles estiverem completamente à esquerda e à direita, ou para cima e para baixo, alterar o z-index não fará diferença. Primeiro, verifique a posição retangular do elemento nas ferramentas de desenvolvedor e determine se existem áreas de sobreposição. Para os padrões de posicionamento de elementos sobrepostos, verifique os padrões de espaço e coordenadas do CSS position: relative, absolute, fixed e sticky.
A posição determina o padrão de coordenadas e a participação no fluxo, e o z-index determina o que fica na frente e atrás quando há sobreposição. Alterar as coordenadas com top e alterar a ordem com z-index são tarefas diferentes. O exemplo abaixo fixa as posições do badge e do card e então altera apenas o z-index do elemento pai, para que você possa comparar as duas funções sem confundi-las.
O z-index pode ser aplicado a elementos posicionados, como relative e absolute, e pode ser usado para itens Flex e itens Grid mesmo que o position seja static. Se você apenas atribuir números a blocos gerais de fluxo comum e esperar efeitos, as condições de aplicação podem não ser atendidas. Você pode verificar o significado do alvo e do valor na descrição do z-index do MDN.
Compare contextos de empilhamento como grupos
Um contexto de empilhamento agrupa seus descendentes para comparações externas de empilhamento. Se o pai à esquerda tiver z-index: 1 e o cartão à direita tiver z-index: 2, um selo filho com z-index: 9999 dentro do contexto esquerdo não compete diretamente com o cartão à direita. O grupo pai permanece abaixo dele.
Left parent context: z-index 1
└ Child badge: z-index 9999
Right card context: z-index 2
Outside, compare parent 1 and card 2.
Elevar o pai esquerdo para z-index: 3 coloca todo o seu contexto acima do cartão à direita em 2. O selo filho mantém seu próprio valor 9999, mas se torna visível na sobreposição. Os números de ancestrais e descendentes não são somados para produzir um valor global como 10000. Veja MDN: Contexto de empilhamento.
Identifique declarações que criam contextos
| Condições representativas | Criar um novo contexto | O que verificar |
|---|---|---|
| relative ou absolute com z-index diferente de auto | Sim | 0 também é um número e é diferente de auto. |
| fixed ou sticky | Sim | Cria contexto mesmo se z-index for auto |
| Item Flex ou Grid + z-index não auto | Sim | Possível sem posição |
| opacity menor que 1 | Sim | Afeta relações de grupo bem como visibilidade |
| transform não é none | Sim | Mesmo que a quantidade de movimento seja 0, é diferente de none |
| isolation: isolate | Sim | Como criar intencionalmente um contexto separado |
A tabela acima é uma lista de condições frequentemente encontradas e não é uma lista de todas as condições de criação. Você deve distinguir entre casos em que apenas relative é especificado e z-index é auto, e casos em que z-index: 0 é especificado para relative. Se a sobreposição mudou, verifique não apenas o número, mas também a opacidade ou transform recém-adicionados ao ancestral.
Dentro do mesmo contexto, você pode comparar a frente e o verso usando o número z-index do elemento que atende às condições de aplicação. No entanto, porque a ordem geral de desenho do CSS tem múltiplos níveis, incluindo níveis negativos, fluxo normal e elementos posicionados, não trate o auto de todos os elementos como igual ao número 0 nem calcule a ordem geral da página apenas com base nos números. A prática de aprendizado restringe as condições a números positivos e ao contexto explícito do pai.
Compare os valores de z-index do pai e do filho
Salve o código abaixo como stacking-context.html e abra-o. O selo é posicionado a 80-144px do topo, e o cartão à direita é colocado na área de 110-230px, com uma sobreposição vertical de 34px. As posições esquerda e direita usam uma proporção em relação à largura do elemento pai para manter a sobreposição no celular. Pais e itens são calculados como border-box e configurados para evitar transbordamento desnecessário fora do contêiner.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>stacking-context.html</title>
<style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.scene { position: relative; width: min(100%, 520px); height: 300px; background: #f1f4f7; }
.left { position: absolute; z-index: 1; left: 0; top: 20px; width: 60%; height: 180px;
padding: 16px; background: #ffe3b5; }
.badge { position: absolute; z-index: 9999; left: 70%; top: 60px; width: 50%; height: 64px;
padding: 8px; background: #f5a7cc; }
.right { position: absolute; z-index: 2; left: 50%; top: 110px; width: 45%; height: 120px;
padding: 12px; background: #9cd4f2; }
.raised .left { z-index: 3; }
</style>
</head>
<body>
<h1>Child and parent z-index values</h1><h2>Parent: 1; right card: 2</h2><div class="scene original"><div class="left">Left parent<div class="badge">Child badge<br>9999</div></div><div class="right">Right card<br>z-index: 2</div></div><h2>Parent: 3; right card: 2</h2><div class="scene raised"><div class="left">Left parent<div class="badge">Child badge<br>9999</div></div><div class="right">Right card<br>z-index: 2</div></div>
</body>
</html>
Na primeira seção, a parte sobreposta do selo rosa fica coberta pelo cartão azul, e na segunda seção, o selo rosa está visível sobre o cartão azul. A única diferença entre as duas zonas é 1 e 3 do pai esquerdo. O diagrama explicativo a seguir ilustra os dois estados com as mesmas coordenadas relativas; não é uma captura de tela do navegador.
- Aumente apenas o valor de z-index de .badge na primeira seção para 99999. O relacionamento entre o Pai 1 e o Cartão 2 é mantido, então a parte sobreposta continua sendo coberta pelo cartão. Restaura o número para 9999.
- Adicione a regra .original .left { z-index: 3; }. O badge vai subir no cartão sem alterar as coordenadas. Após a confirmação, remova a regra adicionada.
- Na primeira seção original, altere apenas o z-index de .left para auto. Neste exemplo, sem outras propriedades de criação, o pai esquerdo não cria um contexto separado, então o contexto do badge é comparado ao cartão externo. Certifique-se de que o badge esteja visível à frente e restaure para 1.
- Ajuste a largura da tela para garantir que o selo e o cartão ainda se sobreponham. Como mudanças numéricas não são visíveis quando as coordenadas estão separadas, as comparações devem ser feitas mantendo a área de sobreposição.
Distinga recorte por overflow e ordem de empilhamento
Se o ancestral trunca o conteúdo com overflow: hidden, as partes fora de seus limites não podem se tornar visíveis apenas com um z-index alto. Se ele estiver à frente na ordem, mas não visível, você precisa determinar se ele está coberto por outro elemento ou cortado no limite de um ancestral. Salve o código abaixo como stacking-clip.html e execute-o. Mesmo que você aumente o z-index, se ele estiver cortado no limite do pai, verifique as condições de corte para CSS Overflow, Quebra de Texto Longo e Reticências.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>stacking-clip.html</title>
<style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.frame { position: relative; width: min(100%, 260px); height: 100px; overflow: hidden;
border: 2px solid #789; background: #e8f5de; }
.popup { position: absolute; z-index: 9999; left: 80%; top: 24px; width: 90px; height: 60px;
padding: 8px; background: #f5a7cc; }
</style>
</head>
<body>
<h1>A box that stays clipped at a higher z-index</h1><div class="frame">Parent boundary<div class="popup">Badge<br>9999</div></div><p>The right side of the badge extends beyond its parent's boundary.</p>
</body>
</html>
- Certifique-se de que o lado direito do badge esteja cortado na borda do elemento pai. Mesmo que você mude o z-index para 99999, a parte truncada não aparecerá. Restaure o número para 9999.
- Altere apenas o overflow de .frame para visible. Outras coordenadas e números permanecem os mesmos, mas a área fora do limite fica visível. Após a comparação, volte para hidden.
Em telas reais, remover o overflow pode afetar outros propósitos, como rolagem e cantos arredondados. Primeiro, determine se a truncagem é intencional e, se o popup deve ficar fora dos limites, mova a estrutura para fora do ancestral que faz a truncagem ou considere um método de exibição separado, conforme apropriado. Não altere o overflow de todos os pais de uma vez apenas porque esconde o menu.
Siga uma sequência de diagnóstico
- Verifique se o elemento realmente existe e não está oculto devido a display·visibility·opacity.
- Verifique as posições retangulares dos dois elementos para ver se há uma área de sobreposição real.
- Percorra o elemento-alvo e seus ancestrais para encontrar declarações que criam um contexto de empilhamento. Determine qual pai comum os contextos concorrentes estão sendo comparados.
- Decida se o valor a alterar pertence ao contexto do filho ou ao do pai. Verifique também os elementos irmãos afetados e ajuste os valores apenas dentro do intervalo necessário.
- Se você não o vir mesmo após alterar a ordem, verifique truncamentos como overflow·clip e outros padrões de coordenadas. Após concluir a comparação, os valores temporariamente modificados são restaurados para seus valores originais.
O z-index de um elemento comum não deve ser visto como um meio de superar uma camada de exibição separada, como um diálogo na camada superior, apenas aumentando o número. Ao solucionar problemas de cartões e badges padrão, é importante primeiro entender o contexto real do elemento pai e o truncamento. Em vez de apenas continuar aumentando os números, você pode configurar a ordem desejada mesmo com valores pequenos, verificando quais grupos são comparados.





