Artigo original: Z-Index Explained: How to Stack Elements Using CSS

Escrito por: Veronika Ivhed

Eu sempre tive dificuldade com a propriedade z-index do CSS (texto em inglês). Parecia muito fácil inicialmente. Elementos com um valor de z-index maior são exibidos na frente daqueles com um valor de z-index menor. Ainda assim, diversas vezes, acabei em situações onde parecia que o valor de z-index não tinha efeito algum.

Decidi que estava na hora de acabar com a tentativa e erro com o z-index e que eu queria entendê-lo melhor. Espero que este artigo ajude você para que nunca mais você precise se perguntar o motivo pelo qual o z-index não estava fazendo aquilo que você esperava que fizesse.

Ordem de sobreposição padrão

Vamos, primeiro, mencionar a ordem padrão que o navegador utiliza para sobrepor elementos quando a propriedade z-index não está aplicada:

  1. Elemento raiz (o elemento <html>)
  2. Elementos não posicionados na ordem em que são definidos
  3. Elementos posicionados na ordem em que são definidos

Um elemento não posicionado é um elemento com o valor padrão da propriedade position, o valor static. Um elemento posicionado é um elemento com qualquer outro valor de position. Exemplos de outros valores são: absolute, relative, sticky e fixed.

HTML:

<div class="pink">
  <div class="orange"></div>
</div>
<div class="blue"></div>
<div class="green"></div>

CSS:

/* Este é o único CSS relevante para o exemplo. Para ver o CSS completo, confira os links abaixo das imagens. */

.blue, .pink, .orange {
  position: absolute;
}
0ok6C2rWIvGF9pibC1xMz9q0iOmkqNWOx1cT
https://codepen.io/ivhed/pen/QrdEBB

Definimos a caixa verde por último no documento. Ainda assim, ela aparece atrás dos outros porque ele não está posicionado.

Sobreposição com z-index

Se quisermos alterar a ordem de sobreposição desses elementos, podemos usar a propriedade z-index. Um elemento com um valor mais alto de z-index será exibido na frente de um elemento com um valor de z-index mais baixo. Algo que é importante observar é o fato de que z-index funciona apenas com elementos posicionados.

.blue, .pink, .orange {
  position: absolute;
}

.blue {
  z-index: 2;
}

.orange {
  z-index: 3;
}

.green {
  z-index: 100; // não tem efeito, já que a caixa verde não está posicionada
}
NOdy4A6ZcslzfIFMD-PW5-vqD83i2Qb5vOrQ
https://codepen.io/ivhed/pen/xjqmpV

A caixa laranja com um valor maior de z-index é exibida na frente da caixa azul.

Contexto de sobreposição

Digamos que queremos adicionar outra caixa posicionada no layout que queremos posicionar atrás da caixa rosa. Atualizamos nosso código assim:

HTML:

<div class=”pink”>
  <div class=”orange”></div>
</div>
<div class=”blue”></div>
<div class=”purple”></div>
<div class=”green”></div>

CSS:

.blue, .pink, .orange, .purple {
  position: absolute;
}

.purple {
  z-index: 0;
}

.pink {
  z-index: 1;
}

.blue {
  z-index: 2;
}

.orange {
  z-index: 3;
}

.green {
  z-index: 100;
}
Uuw9yAx1sVpyVHZ8sCRtVF8H5eBnyCElCH4S
https://codepen.io/ivhed/pen/YLZdjx

Nossa caixa rosa é exibida na frente da caixa roxa como era esperado, mas o que houve com a caixa laranja? Por que ela se encontra, de repente, atrás da caixa azul, embora tenha um valor de z-index maior? Isso ocorre porque adicionar um valor de z-index a um elemento gera o que chamamos de contexto de sobreposição (texto em inglês).

A caixa rosa tem um valor de z-index diferente de auto, o que gera um novo contexto de sobreposição. O fato de que ele forma um contexto de sobreposição afeta o modo como seus elementos filhos são exibidos.

É possível alterar a ordem de sobreposição dos elementos filhos da caixa rosa. Porém, o z-index deles somente tem um significado dentro daquele contexto de sobreposição. Isso significa que não conseguiremos mover a caixa laranja para frente da caixa azul, pois eles já não estão dentro do mesmo contexto de sobreposição.

Se quisermos que a caixa azul e a caixa laranja sejam parte do mesmo contexto de sobreposição, podemos definir a caixa azul como um elemento filho da caixa rosa. Isso fará com que a caixa azul apareça atrás da caixa laranja.

<div class="pink">
  <div class="orange"></div>
  <div class="blue"></div>
</div>
<div class="purple"></div>
<div class="green"></div>
T-Z7bkfgeKlqiz8WYbAlU0W9RMM4CtJgxw50
https://codepen.io/ivhed/pen/erGoJE

Os contextos de sobreposição não são formados apenas quando aplicamos z-index a um elemento. Há várias outras propriedades (texto em inglês) que fazem com que elementos criem contextos de sobreposição. Alguns exemplos disso são filter, opacity e transform.

Vamos voltar ao nosso exemplo anterior. A caixa azul está novamente no mesmo nível que a caixa rosa. Desta vez, em vez de adicionar um z-index à caixa rosa, vamos aplicar um filter (texto em inglês) a ela.

HTML:

<div class="pink">
  <div class="orange"></div>
</div>
<div class="blue"></div>
<div class="green"></div>

CSS:

.blue, .pink, .orange {
  position: absolute;
}

.pink {
  filter: hue-rotate(20deg);
}

.blue {
  z-index: 2;
}

.orange {
  z-index: 3;
}

.green {
  z-index: 100;
}
JI1HNPrHCEUbKSZZiKSJLnBlWLyJKPclyEez
https://codepen.io/ivhed/pen/LmWMQb

A caixa laranja ainda tem um valor de z-index maior do que a caixa azul, mas é exibida por trás dela. Isso ocorre porque o valor de filter fez com que a caixa rosa formasse um novo contexto de sobreposição.

Resumo

Ao usar z-index em elementos posicionados, podemos alterar o valor padrão da ordem de sobreposição.

Ao aplicar determinadas propriedades do CSS, um elemento pode formar um contexto de sobreposição. Os valores de z-index somente terão algum significado dentro desse mesmo contexto de sobreposição.

Para mais informações sobre o z-index, recomendo a leitura deste artigo. Ele me deu muita inspiração para escrever este artigo.

Obrigado pela leitura! 🙂