Artigo original: https://www.freecodecamp.org/news/4-reasons-your-z-index-isnt-working-and-how-to-fix-it-coder-coder-6bc05f103e6c/

A propriedade z-index do CSS permite posicionar elementos em camadas uns sobre os outros. Ela é muito útil e, honestamente, uma ferramenta muito importante que você deve saber como usar no CSS.

Infelizmente, o z-index é uma daquelas propriedades que nem sempre se comporta de maneira intuitiva. A princípio, ela parece simples — um número com o z-index mais alto significa que o elemento estará em cima dos elementos com números de z-index mais baixos. Mas existem algumas regras adicionais que tornam as coisas mais complicadas. E nem sempre é possível consertar as coisas ajustando o z-index para 999999!

Este artigo explicará em detalhes quatro das razões mais comuns para o z-index não funcionar, e como você pode resolvê-las.

Vamos passar por alguns exemplos reais de código. Após ler este artigo, você será capaz de entender e evitar essas armadilhas comuns do z-index!

Vamos verificar o primeiro motivo:

1. Os elementos no mesmo contexto de empilhamento serão exibidos na ordem em que aparecem, com os últimos elementos em cima dos primeiros.

Em nosso primeiro exemplo, temos um layout relativamente simples que inclui 3 elementos principais:

  • Uma imagem de um gato
  • Um bloco branco com um texto
  • Outra imagem do mesmo gato

Aqui está o HTML do nosso exemplo:

<div class="cat-top"></div> 

<div class="content__block"> Meow meow meow... </div> 

<div class="cat-bottom"></div>

Neste layout, queremos que o bloco branco com o texto esteja em cima dos dois gatos.

Para tentarmos conseguir isso, adicionamos margens negativas ao CSS para ambas as imagens de gatos, de modo que elas se sobreponham um pouco sobre o bloco branco:

.cat-top { 
   margin-bottom: -110px; 
} 

.cat-bottom { 
   float: right; 
   margin-top: -120px; 
}

No entanto, esta é a aparência:

O primeiro gato está de fato posicionado sob o bloco de conteúdo branco, exatamente como nós queremos., mas a imagem do segundo gato está posicionada acima do bloco!

Por que isso ocorre?

O motivo para esse comportamento é a ordem natural de empilhamento na página da web. Essas diretrizes basicamente determinam quais elementos estarão acima e quais estarão abaixo.

Mesmo que os elementos não tenham o z-index definido, há sempre um motivo para algum deles estar acima.

Em nosso caso, nenhum dos elementos tem um valor de z-index. Assim, sua ordem de empilhamento é determinada pela ordem de aparecimento. De acordo com essa regra, elementos que aparecem depois na sequência de marcação estarão acima dos elementos que vêm antes (você pode ler mais sobre as diretrizes da ordem de empilhamento na Mozilla Developer Network aqui - texto em inglês).

No nosso exemplo, com os gatos e o bloco branco, eles estão obedecendo essa regra. É por isso que o primeiro gato está abaixo do elemento do bloco branco e o bloco branco está abaixo do segundo gato.

Certo, a ordem de empilhamento está ok, mas como consertamos o CSS de modo que o segundo gato fique abaixo do bloco branco?

Vamos dar uma olhada no segundo motivo:

2. O elemento não tem sua posição definida

Uma das outras orientações que determinam a ordem de empilhamento é o fato de o elemento ter ou não a propriedade position definida.

Para definir a propriedade position de um elemento, adicione position ao seu CSS com qualquer valor que não seja static, como relative ou absolute (você pode ler mais sobre isso neste artigo que eu escrevi - texto em inglês).

De acordo com essa regra, os elementos posicionados serão exibidos acima dos elementos não posicionados.

Desse modo, definir o bloco branco de modo que tenha a propriedade position: relative e deixar os dois elementos com gatos sem posicionamento fará com que o bloco branco fique acima dos gatos na ordem de empilhamento.

Essa será a aparência – você também pode brincar com o Codepen acima.

NlDhNhhBXrXmR35aZCt4XCGbfBCt4bRPLHzK

U-húuuuu!

Agora, a próxima coisa a fazer é girar o gato de baixo ao contrário, usando a propriedade transform. Desse modo, os dois gatos estarão abaixo do bloco branco, mas somente com suas cabeças aparecendo.

Fazer isso, no entanto, causará mais uma confusão relacionada com o z-index. Trataremos do problema e da solução na próxima parte.

3. Definir algumas propriedades do CSS, como opacity ou transform, colocará o elemento em um novo contexto de empilhamento.

Como acabamos de mencionar, queremos girar o gato de baixo ao contrário. Para conseguir isso, adicionamos transform: rotate(180deg).

.cat-bottom { 
   float: right; 
   margin-top: -120px; 
   transform: rotate(180deg); 
}

Isso, porém, faz com que o gato de baixo seja exibido acima do bloco branco novamente!

GTJjexmzYUkJa37hDuIUALqGngUjSl0wxFcE

O que está acontecendo aqui?

Você pode não encontrar esse problema com frequência, mas um outro aspecto da ordem de empilhamento é o fato de que algumas propriedades do CSS, como transform e opacity, colocarão o elemento em um novo contexto de empilhamento (texto em inglês) próprio.

Isso significa que adicionar a propriedade transform ao elemento .cat-bottom faz com que ele se comporte como se tivesse um z-index de 0, mesmo que não tenhamos definido sua position nem seu z-index! A W3.org tem uma documentação informativa, embora bastante densa, sobre como funciona a propriedade opacity.

Lembre-se, em nenhum momento adicionamos o valor z-index ao bloco branco, somente position: relative. Isso foi o suficiente para posicionar o bloco branco acima dos gatos não posicionados.

Porém, como o elemento .bottom-cat está agindo como se estivesse posicionado relativamente com z-index: 0, transformá-lo posicionou o gato acima do bloco branco.

A solução para isso é definir position: relative e definir explicitamente z-index pelo menos no bloco branco. Você pode ir um pouco mais longe e definir position: relative e um z-index menor para os elementos dos gatos, simplesmente por garantia.

.content__block { 
   position: relative; 
   z-index: 2; 
} 

.cat-top, .cat-bottom { 
   position: relative; z-index: 1; 
}

Na minha opinião, fazer isso resolverá a maioria, se não todas as questões mais básicas relacionadas ao z-index.

Bem, vamos passar agora ao último motivo pelo qual o z-index pode não funcionar. Este é um pouco mais complexo, pois envolve elementos pais e filhos.

4. O elemento está em um contexto de empilhamento menor devido ao nível de z-index do elemento pai

Vamos conferir nosso exemplo de código para isso:

Eis o que temos: uma página da web simples com conteúdo normal, e uma guia lateral rosa dizendo "Send Feedback" (Enviar feedback), posicionada acima do conteúdo.

Então, quando você clica na foto do gato, uma janela de modal se abre com um fundo cinza transparente de sobreposição.

Porém, mesmo quando a janela modal está aberta, a guia lateral segue acima da sobreposição cinza. Queremos que a sobreposição seja exibida sobre tudo, incluindo a guia lateral.

Vamos dar uma olhada no CSS dos elementos em questão:

.content { 
   position: relative; 
   z-index: 1; 
} 

.modal { 
   position: fixed; 
   z-index: 100; 
} 

.side-tab { 
   position: fixed; 
   z-index: 5; 
}

Todos os elementos têm suas posições definidas. A guia lateral tem um z-index de 5, que a posiciona sobre o elemento do conteúdo, que tem um z-index: 1.

Em seguida, temos o modal, com z-index: 100, o que deveria colocá-lo acima da guia lateral, com z-index: 5. Em vez disso, a sobreposição do modal fica abaixo da guia lateral.

Por que isso ocorre?

Anteriormente, tratamos de alguns fatores que são importantes para o contexto de empilhamento, como o elemento ter sua posição definida e sua ordem na marcação.

Existe, contudo, outro aspecto da ordem de empilhamento: o elemento filho é limitado ao contexto de empilhamento de seu pai.

Vamos examinar mais a fundo os três elementos em questão.

Aqui vemos a marcação:

<section class="content">            
    <div class="modal"></div>
</section>

<div class="side-tab"></div>

Olhando para ela, podemos ver que os elementos content (conteúdo) e side-tab (guia lateral) são irmãos, ou seja, que eles existem no mesmo nível da marcação (o que é diferente do nível do z-index). Também vemos que o modal é um elemento filho do elemento content.

Como o modal está dentro do elemento content, seu z-index de 100 tem efeito apenas dentro do pai, o elemento content. Por exemplo, se houvesse outros elementos filhos de content e irmãos do modal, seus valores de z-index os colocariam acima ou abaixo uns dos outros.

O valor de z-index desses elementos filhos, no entanto, não significam nada fora do pai, pois o elemento pai content tem um z-index definido como 1.

Assim, seus filhos, incluindo o modal, não conseguem sair daquele nível do z-index.

Você pode se lembrar desta regra por meio de uma metáfora levemente deprimente: um filho pode estar limitado ao seus pais e não conseguir se libertar deles.

Existem algumas soluções para esse problema:

Solução: mover o modal para fora do elemento pai content e colocá-lo no contexto de empilhamento principal da página.

A marcação correta teria, então, esta aparência:

<section class="content"></section>

<div class="modal"></div>

<div class="side-tab"></div>

Agora, o elemento modal é irmão dos outros dois elementos. Isso coloca os três elementos no mesmo contexto de empilhamento. Assim, seus níveis de z-index afetarão uns aos outros.

Nesse novo contexto de empilhamento, os elementos serão exibidos na seguinte ordem, de cima para baixo:

  • modal (z-index: 100)
  • guia lateral (z-index: 5)
  • conteúdo (z-index: 1)

Solução alternativa: remover o posicionamento de content, para que ele não limite o z-index do modal.

Se não quiser ou não puder mudar a marcação, você pode resolver o problema removendo a configuração de position do elemento content:

.content { 
   // Sem posição definida
} 

.modal { 
   position: absolute; 
   z-index: 100; 
} 

.side-tab { 
   position: absolute; 
   z-index: 5; 
}

Como o elemento content agora não está posicionado, ele não limitará mais o valor de z-index do modal. Assim, o modal aberto será posicionado acima do elemento da guia lateral, devido ao seu z-index maior, de 100.

Embora isso dê certo, pessoalmente, eu prefiro a primeira solução, pois se, por alguma razão no futuro, você tiver de posicionar o elemento content, ele limitará novamente a ordem do modal no contexto de empilhamento.

Em resumo

Espero que você tenha achado útil este tutorial! Para resumir, a maioria dos problemas com o z-index pode ser resolvida seguindo essas duas orientações:

  1. Verificar se os elementos têm a propriedade position definida e os valores de z-index na ordem correta.
  2. Verificar se não há elementos pai limitando o nível de z-index de seus filhos.

Quer mais informações?

A autora está criando um curso sobre design responsivo! Inscreva-se aqui para receber um e-mail quando o curso for publicado (site em inglês).

A autora escreve tutoriais sobre desenvolvimento para a web em seu blog, coder-coder.com, publica minidicas no Instagram e tutoriais de programação no YouTube.