Artigo original: CSS Z-Index Not Working? How to Fix It Using Stack Order
A propriedade z-index
do CSS pode ser bastante complicada. Ela não funciona facilmente e por conta própria se você não souber como usá-la adequadamente.
Neste artigo, explicarei o que é a propriedade z-index
, o que é a ordem de empilhamento e como usá-las da maneira certa.
Darei alguns exemplos comuns do funcionamento inadequado da propriedade z-index
e mostrarei as soluções para eles.
O que é o z-index?
Em primeiro lugar, a letra Z vem da representação das três dimensões: x, y e z. x e y são a largura e a altura. A 3ª dimensão, z, é a profundidade:
O CSS fornece uma propriedade chamada z-index
para que possamos usá-la para determinar a profundidade de um elemento. À medida que o valor de z-index
de um elemento aumenta, mais à frente dos outros elementos ele estará posicionado com relação à 3ª dimensão.
Vejamos alguns exemplos e como usar a propriedade z-index
corretamente.
A propriedade z-index não funciona sem uma posição definida nem com position: static
A primeira coisa importante a se saber é que todo elemento de uma página da web tem uma posição padrão – em outras palavras, uma posição definida estaticamente (por padrão). Digamos que temos uma caixa vermelha e outra azul em nossa página:
<div class="caixa caixa-vermelha"></div>
<div class="caixa caixa-azul"></div>
Se aplicarmos z-index
às caixas diretamente, você verá que isso não dará resultado. Isso ocorre por não termos ainda uma posição (a propriedade position) definida:
.caixa {
height: 150px;
width: 150px;
}
.caixa-vermelha {
background: red;
z-index: 1;
}
.caixa-azul {
background: #00d5f1;
bottom: 80px;
left: 55px;
z-index: 2;
}
Esse é um dos exemplos mais comuns da propriedade z-index
, onde ela não funciona corretamente. Para resolvê-lo, podemos aplicar uma propriedade position (texto em inglês) à classe caixa
. Isto resolverá a questão:
.caixa {
height: 150px;
width: 150px;
position: relative;
}
Você também pode assistir a este tutorial em vídeo para ver um exemplo de uso de z-index
:
O que é a ordem de empilhamento?
Se removermos as propriedades z-index
das duas caixas, a caixa azul seguira à frente da caixa vermelha, mesmo sem um valor para a propriedade z-index
:
.caixa {
height: 150px;
width: 150px;
position: relative;
}
.caixa-vermelha {
background: red;
}
.caixa-azul {
background: #00d5f1;
bottom: 80px;
left: 55px;
}
A renderização será a seguinte:
Desse modo, quando todos os elementos estão no mesmo nível, um elemento ainda ficará à frente do outro, pois eles também têm uma ordem padrão em termos do eixo z. Essa ordem é chamada de ordem de empilhamento.
Como no exemplo acima, quando não há uma propriedade z-index
aplicada a um elemento, os navegadores usam uma ordem de empilhamento padrão para empilhar os elementos na página:
1. O segundo plano e as bordas do elemento root
2. Blocos descendentes não posicionados, em ordem de aparecimento no HTML
3. Blocos descendentes posicionados, em ordem de aparecimento no HTML
Fonte: Stacking without the z-index property (texto em inglês)
Observe que o elemento root é o elemento <html>
. Os elementos não posicionados são aqueles que têm a propriedade position com seu valor padrão, position: static
, e os elementos posicionados são aqueles que têm elementos com position
definida como outro valor.
Se adicionarmos outra caixa, mas se definirmos sua propriedade position
com o valor padrão static
, ela aparecerá atrás das caixas vermelha e azul:
<div class="caixa caixa-vermelha"><p>Positioned</p></div>
<div class="caixa caixa-azul"><p>Positioned</p></div>
<div class="caixa caixa-amarela"><p>Non-positioned</p></div>
.caixa {
height: 150px;
width: 150px;
position: absolute;
}
p {
color: #0a0a23;
margin: 0;
padding-left: 5px;
}
.caixa-vermelha {
background: red;
top: 40px;
left: 27px;
}
.caixa-azul {
background: #00d5f1;
top: 80px;
left: 55px;
}
.caixa-amarela {
background: rgb(251, 239, 0);
position: static;
}
Este é o resultado:
Embora tenhamos modificado as caixas azul e vermelha para que usassem position: absolute
em vez de relative
e tenhamos ajustado um pouco seu posicionamento, a ideia era auxiliar a perceber a ordem padrão de empilhamento no navegador – elementos posicionados no mesmo nível sempre aparecerão sobre os elementos não posicionados (ou com a propriedade definida como position: static
).
Você pode estar se perguntando o que acontece quando os elementos não estiverem no mesmo nível. Veremos isso agora.
Contexto de empilhamento: Como o z-index do elemento pai se aplica também ao elemento filho
Vamos colocar a caixa amarela entre a caixa vermelha e a azul:
<div class="caixa caixa-vermelha">
<div class="caixa caixa-amarela"></div>
</div>
<div class="caixa caixa-azul"></div>
.caixa-vermelha {
background: red;
z-index: 1;
}
.caixa-azul {
background: #00d5f1;
bottom: 80px;
left: 55px;
z-index: 2;
}
.caixa-amarela {
background: rgb(251, 239, 0);
left: 25px;
top: 25px;
z-index: 3;
}
Teremos renderizado o seguinte:
Como é possível ver no código, mesmo que a caixa amarela tenha um valor dez-index
maior em comparação ao elemento azul, ela está posicionada atrás da caixa azul.
Isso ocorre porque a caixa amarela agora é "filha" da caixa vermelha. O z-index
do elemento "pai" sempre se aplica aos seus filhos também. Como o elemento pai tem um z-index
menor que o da caixa azul, seus elementos filhos herdarão o mesmo valor de z-index
e ficarão abaixo da caixa com o valor de z-index
maior no mesmo nível que o elemento pai.
Isso ocorre por causa de algo chamado contexto de empilhamento. Colocado de maneira simples, um contexto de empilhamento é como uma nova instância da lista da ordem de empilhamento mencionada anteriormente, ou seja:
- Um elemento root (<html>)
- Elementos não posicionados (com
position: static
) na ordem em que aparecem - Elementos posicionados (com
position
definida com outro valor que nãostatic
) na ordem em que aparecem
O que devemos lembrar é que o elemento posicionado com um valor de z-index
diferente do padrão auto
(que o deixará com posicionamento estático) criará sempre um outro contexto de empilhamento.
Se olharmos para o HTML acima, como a caixa vermelha tem um z-index
de 1, ela cria outro contexto de empilhamento para seus filhos – no caso, para a caixa amarela. Nesse contexto de empilhamento, a caixa vermelha funciona como se fosse o elemento root do HTML. A caixa amarela estaria posicionada dentro desse elemento root.
Assim, como a caixa azul é parte do mesmo contexto de empilhamento que a caixa vermelha (onde o elemento <html>
é o que serve como elemento root), ela sempre aparecerá acima da caixa amarela.
Caso veja esse tipo de problema, você pode resolvê-lo removendo o elemento filho de dentro do elemento pai ou removendo a propriedade position
do elemento pai, de modo que o z-index
do pai não afete seus filhos:
<div class="caixa caixa-vermelha"></div>
<div class="caixa caixa-amarela"></div>
<div class="caixa caixa-azul"></div>
.caixa {
height: 150px;
width: 150px;
position: relative;
}
.caixa-vermelha {
background: red;
z-index: 1;
}
.caixa-azul {
background: #00d5f1;
bottom: 240px;
left: 55px;
z-index: 2;
}
.caixa-amarela {
background: rgb(251, 239, 0);
bottom: 120px;
left: 25px;
z-index: 3;
}
Agora, o que temos é:
Saiba que existem diversas outras propriedades que podem afetar o contexto de empilhamento de um elemento. Leia mais sobre isso aqui (texto em inglês).
Isso é um pouco contraintuitivo, mas é uma das razões para o não funcionamento da propriedade z-index
.
Não atribua números grandes ao z-index
Outro motivo comum para o z-index
não funcionar corretamente é a atribuição de números muito altos à propriedade z-index
:
.caixa-azul {
z-index: 9999;
}
Em alguns projetos nos quais já trabalhei, vi pessoas atribuírem esses valores muito grandes, como 9999, ao z-index
de um elemento.
Funciona, mas é como usar um martelo quando o que você precisa é de uma chave de fenda.
Imagine o seguinte – você chega em um projeto grande e trabalha com o HTML, mas, não importa o que você tente, não consegue colocar os elementos na ordem correta. Assim, após pesquisar um pouco on-line, você descobre que alguém, em algum momento, definiu uma propriedade z-index
global como 9999, que segue sobrescrevendo seu z-index
.
Agora que você sabe como usar a propriedade z-index
adequadamente e que entende o contexto de empilhamento, não precisará mais usar valores enormes como aquele. 🙂
Espero que este artigo tenha ajudado você a entender melhor como usar a propriedade z-index
, assim como a ordem de empilhamento e o contexto do empilhamento. Se quiser aprender mais sobre desenvolvimento para a web, não deixe de se inscrever no canal do YouTube do autor.
Agradecemos pela leitura!