O valor do z-index: como organizar camadas sem números mágicos
O valor do z-index: mais importante do que você imagina
A propriedade z-index é uma das ferramentas mais importantes que qualquer desenvolvedor UI tem à disposição, pois permite controlar a ordem de sobreposição dos elementos em uma página web. Modais, toasts, popups, dropdowns, tooltips e muitos outros elementos comuns dependem dela para garantir que apareçam acima do restante do conteúdo.
Enquanto a maioria das fontes foca nos detalhes técnicos ou nas armadilhas comuns do Stacking Context, acredito que elas deixam de fora um aspecto fundamental e potencialmente caótico do z-index: o valor em si.
O problema dos números mágicos
Nos projetos, ao atingirmos certo tamanho, os valores de z-index tornam-se uma bagunça de “números mágicos”, um campo de batalha caótico onde cada equipe tenta superar as outras com números cada vez maiores.
Vírios anos atrás, vi essa linha em um pull request:
z-index: 2147483647;
Pensei comigo: “Wow, esse é um número grande! Por que escolheram aquele valor específico?” Quando perguntei ao autor, ele respondeu: “Bem, só queria garantir que ficasse acima de todos os outros elementos da página, então escolhi um número alto.”
Isso me fez refletir sobre como olhamos para a ordem de sobreposição em nossos projetos, como escolhemos valores de z-index e, mais importante, as implicações dessas escolhas.
A raiz do problema não é técnica
O problema central não é técnico, mas de visibilidade. Em um projeto grande com múltiplas equipes, nem sempre sabemos o que mais flutua na tela. Pode haver uma notificação toast da equipe A, um banner de cookies da equipe B ou um modal do SDK de marketing.
A lógica do desenvolvedor era simples nesse caso: “Se usar um número realmente alto, certamente ficará no topo.”
O conceito de Stacking Context é essencial
Como mencionei no início, existem muitas fontes que cobrem z-index no contexto do Stacking Context. Neste artigo, não abordaremos esse tópico. No entanto, é impossível falar sobre valores de z-index sem mencionar pelo menos isso, pois é um conceito crucial para entender.
Essencialmente, elementos com valor de z-index maior serão exibidos na frente dos que têm valor menor, desde que estejam no mesmo Stacking Context.
Dica: O valor máximo para z-index é 2147483647. Por que esse número específico? É o valor máximo para um inteiro sinalizado de 32 bits. Se tentar ir mais alto, a maioria dos navegadores simplesmente o limita a esse valor.
O perigo dos valores arbitrários altos
Usar valores arbitrários altos para z-index pode levar a vários problemas:
- Criação de dependência entre equipes sem sistema padronizado
- Dificuldade em prever o comportamento visual final
- Mudanças futuras que quebram a hierarquia estabelecida
- Manutenção complexa quando elementos precisam ser reordenados
A solução: tokenização de valores de z-index
Agora, espere, aguentem comigo! Sei que no momento em que alguém menciona “tokens”, alguns desenvolvedores podem fechar os olhos ou dar de ombros, mas essa abordagem realmente funciona. A maioria dos principais (e melhor desenhados) design systems inclui tokens de z-index por um motivo.
Implementação prática com tokens globais
Vamos ver como isso funciona na prática. Preparei uma demonstração simples onde gerenciamos nossas camadas através de um conjunto central de tokens em :root:
:root {
–z-base: 10;
–z-overlay: 20;
–z-modal: 30;
–z-toast: 40;
}
Esse setup é incrivelmente conveniente. Se precisar adicionar um novo popup ou toast, sabe exatamente qual z-index usar. Se quiser mudar a ordem — por exemplo, colocar toasts acima do overlay — não precisa caçar dezenas de arquivos. Basta alterar os valores em :root, e tudo se atualiza de uma vez.
Escalabilidade com tokens locais
O verdadeiro poder desse sistema brilha quando seus requisitos mudam. Suponha que precise adicionar um novo sidebar e colocá-lo especificamente entre o conteúdo base e os toasts.
Num setup tradicional, você estaria verificando cada elemento existente para ver quais números usam. Com tokens, simplesmente inserimos um novo token e ajustamos a escala:
:root {
–z-base: 10;
–z-sidebar: 25; /* Novo token */
–z-overlay: 30;
–z-modal: 40;
–z-toast: 50;
}
Não precisa tocar em nenhum componente existente com esse setup. Atualiza os tokens e está pronto. A lógica da sua aplicação permanece consistente, e você não mais adivinha qual número é “alto o suficiente”.
Camadas relativas com calc()
Muitas vezes queremos “trancar” camadas específicas umas em relação às outras. Um ótimo exemplo disso é um elemento de fundo para um modal ou overlay. Em vez de criar um token separado para o fundo, podemos calcular sua posição relativa à camada principal.
.overlay {
background: var(–z-overlay);
}
.modal-content {
background: calc(var(–z-overlay) – 1);
}
Isso garante que o fundo ficará sempre exatamente um passo atrás do overlay, não importa qual valor atribuirmos ao –z-overlay.
Tokens globais vs. tokens locais
Há até agora, focamos nas camadas principais e globais da aplicação. Mas o que acontece dentro dessas camadas?
Os tokens criados para as camadas principais (como 100, 200, etc.) não são adequados para gerenciar elementos internos. Isso porque a maioria desses componentes principais cria seu próprio Stacking Context. Dentro de um popup que tem z-index: 300, um valor de 301 é funcionalmente idêntico a 1.
Nota: Para esses tokens locais funcionarem como esperado, você deve garantir que o container crie um Stacking Context. Se estiver trabalhando em um componente que não já tem um (por exemplo, ele não tem z-index definido), pode criar um explicitamente usando isolation: isolate.
Tokens locais para posicionamento interno
Para resolver isso, podemos introduzir um par de “tokens” locais especificamente para uso interno:
:root {
–z-top-local: 10;
–z-bottom-local: -10;
}
Isto nos permite gerenciar posicionamento interno com precisão. Se precisar de um botão de ação flutuante dentro de um popup para ficar no topo, ou um ícone decorativo em um toast para ficar atrás do conteúdo principal, podemos usar esses âncoras locais:
.floating-action-button {
z-index: var(–z-top-local);
}
.toast-icon {
z-index: var(–z-bottom-local);
}
Para layouts internos ainda mais complexos, você pode usar calc() com esses tokens locais. Se tiver múltiplos elementos empilhados dentro de um componente, calc(var(–z-top-local) + 1) (ou – 1) dá esse extra de precisão sem precisar olhar para valores globais.
Tokens negativos como ferramenta poderosa
Até agora, focamos nas camadas principais e globais da aplicação. Mas o que acontece dentro dessas camadas?
Os tokens criados para as camadas principais (como 100, 200, etc.) não são adequados para gerenciar elementos internos. Isso porque a maioria desses componentes principais cria seu próprio Stacking Context. Dentro de um popup que tem z-index: 300, um valor de 301 é funcionalmente idêntico a 1.
Dica: Tokens negativos podem assustar desenvolvedores. Nos preocupamos que um elemento com z-index: -1 desapareça atrás do fundo da página ou algum pai distante. No entanto, dentro de nossa abordagem sistemática, valores negativos são uma ferramenta poderosa para decorações internas.
Tooltip como exemplo prático
Um dos maiores problemas em CSS é gerenciar componentes que podem aparecer em qualquer lugar, como um tooltip. Tradicionalmente, desenvolvedores dão tooltips um z-index massivo (como 9999) porque podem aparecer sobre um modal.
Com nossos tokens locais, podemos parar de jogar adivinhação:
.tooltip {
z-index: var(–z-top-local);
}
Seja o tooltip em um botão no conteúdo principal, um ícone dentro de um toast ou um link dentro de um popup, ele sempre aparecerá corretamente acima do seu entorno imediato. Não precisa saber sobre a “corrida armamentista” global porque já está parado no “chão estável” fornecido pelo token da camada pai.
Regras de ouro para trabalhar com z-index
Para manter um código limpo e escalável, aqui estão as regras de ouro para trabalhar com z-index:
- Sempre use tokens em vez de valores literais
- Diferencie camadas globais de locais
- Use calc() para relações precisas entre elementos
- Crie Stacking Context quando necessário
- Documente a hierarquia de z-index em seu design system
- Implemente ferramentas de enforcement automático
Conclusão: o valor está no sistema, não no número
Seguindo essas regras, transformamos z-index de uma fonte caótica de bugs em uma parte previsível e gerenciável do seu design system. O valor do z-index não está em quão alto é o número, mas no sistema que o define.
Um sistema é tão bom quanto sua enforcement. Em um ambiente com prazos apertados, é fácil para um desenvolvedor inserir um rápido z-index: 999 para “fazer funcionar”. Sem automação, seu belo sistema de tokens eventualmente se erode de volta ao caos.
Para prevenir isso, desenvolvi uma biblioteca especificamente desenhada para forçar exatamente esse sistema: z-index-token-enforcer.
Com essas ferramentas, transformamos as “Regras de Ouro” em um requisito obrigatório, garantindo que seu códigobase permaneça limpo, escalável e, mais importante, previsível.
Por Maya Pixel
Responsável editorial por UI.
Especialista em UI/UX e Web Design Minimalista.
Por Maya Pixel
Responsável editorial por UI.
Especialista em UI/UX e Web Design Minimalista.
Share this content:
Guias relacionados
Se este tema te interessa, estes hubs ajudam a continuar a leitura sem depender de busca nova.



Publicar comentário