Capítulo 27
Position e z-index
5 min de leitura 940 palavras 2 gravuras
Esta é o capítulo 27 de 52 do volume Aprenda a Web. O projeto-fio é a Oficina Costeira, um coletivo fictício de design em João Pessoa. Os nomes, as fotos e os encontros são inventados. O exemplo está em exemplos/27-position-z-index/. Em cada capítulo: leia, copie, mude uma coisa, preveja o resultado, recarregue e confira.
O que você vai aprender
- Distinguir
static,relative,absoluteefixed. - Mover uma caixa com
top,right,bottomeleft. - Criar um contexto de posicionamento no ancestral.
- Empilhar camadas com
z-index. - Centralizar um título sobre um cartaz sem JavaScript.
- Usar
positionsó quando o fluxo normal não chega.
O fluxo primeiro
O navegador empilha os blocos de cima para baixo. Flexbox e Grid resolvem a maior parte do layout da Oficina Costeira. position entra quando você precisa sobrepor, grudar ou sair do fluxo.
static é o valor inicial. A caixa ocupa o lugar que o HTML descreve. top não desloca uma caixa estática. z-index também não atua numa caixa estática comum, mas pode atuar quando ela é um item de Flexbox ou Grid.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Camadas — Oficina Costeira</title>
<link rel="stylesheet" href="assets/stylesheets/main.css">
</head>
<body>
<main>
<div class="azul">Identidade</div>
<div class="roxo">Publicação</div>
<div class="verde">Oficina</div>
</main>
</body>
</html>
Leia o HTML. Copie para um arquivo de teste. Mude a ordem das três div. Preveja quem aparece primeiro. Recarregue e confira.
Erro comum: aplicar position em tudo porque “o cartão não ficou no lugar”. Volte ao fluxo. Ajuste margem, gap ou Flexbox antes de sair da fila.
Absolute tira do fluxo
position: absolute remove a caixa da fila. Os irmãos ocupam o espaço que ela deixou. A largura encolhe até o conteúdo, como no float. Declare width quando a caixa precisar de um tamanho estável.
.roxo {
position: absolute;
width: 12rem;
}
O sistema de coordenadas usa top, right, bottom e left. Números negativos também valem. Combine lados opostos só se quiser esticar a caixa.
Sem um ancestral que estabeleça a referência, as coordenadas usam o bloco inicial, associado à área da janela. O cartaz da orla então “voa” até a borda da página, não até o cartão da oficina.

Mude right de 0 para 2rem. Preveja o deslocamento. Recarregue.
Relative cria o contexto
position: relative no ancestral redefine a origem. O filho absolute passa a medir a partir dessa caixa, não do bloco inicial.
.cartaz {
position: relative;
}
.selo {
position: absolute;
right: 1rem;
bottom: 1rem;
}
<article class="cartaz">
<h2>Encontro na Praia do Jacaré</h2>
<p class="selo">Vagas fictícias</p>
</article>
O selo fica no canto do cartaz. O título continua no fluxo e empurra o que vem depois.
relative também desloca a própria caixa sem tirá-la da fila. Os irmãos reservam o espaço original. Use isso para um ajuste pequeno, não para montar a página.
Erro comum: colocar relative no elemento que você quer mover, e não no pai. O selo então ancora na janela. Confira no inspetor quem é o ancestral posicionado.
Centralizar sem adivinhar a largura
O título sobre o cartaz precisa ficar no meio, mesmo se o texto mudar de tamanho.
.cartaz {
position: relative;
}
.cartaz h2 {
position: absolute;
bottom: 1em;
left: 50%;
transform: translateX(-50%);
margin: 0;
}
left: 50% leva a borda esquerda ao centro. translateX(-50%) recua metade da largura do próprio título. Para o eixo vertical, use top: 50% e translateY(-50%).
Copie o bloco. Mude o texto do h2 para uma frase longa. Preveja se o centro se mantém. Recarregue.
Fixed gruda na janela
position: fixed também sai do fluxo. A origem é a janela. A caixa não acompanha o scroll.
.aviso {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 4;
}
Na Oficina Costeira o skip-link usa um truque parecido: fica fora da tela até receber foco.
.skip {
position: absolute;
left: -999px;
top: 0;
}
.skip:focus {
left: 0.5rem;
top: 0.5rem;
z-index: 10;
}
fixed em menu no celular costuma cobrir conteúdo e brigar com a barra do navegador. Prefira um cabeçalho no fluxo. Se grudar, reserve padding-top no main para o texto não ficar escondido.
Erro comum: fixed no nav sem largura. A caixa encolhe e o menu some pela metade. Declare width ou left e right.
z-index e a ordem das camadas
z-index controla a ordem das camadas. Funciona em caixas posicionadas e em itens de Flexbox ou Grid. Dentro do mesmo contexto de empilhamento, um número maior coloca a caixa à frente. Não precisa de 9999: compare com os vizinhos do mesmo contexto.
.azul {
position: absolute;
top: 0;
left: 20%;
z-index: 1;
}
.roxo {
position: absolute;
top: 0;
left: 30%;
z-index: 2;
}
Nos exemplos de caixas posicionadas deste capítulo, com z-index: auto, a caixa que vem depois no HTML aparece à frente. Um contexto de empilhamento agrupa suas camadas. Por exemplo, position: relative junto de z-index: 0 no pai cria esse grupo. relative sozinho estabelece a referência de posicionamento, mas não cria esse contexto de empilhamento. Os números dos filhos são comparados dentro do grupo.

Mude só o z-index do azul para 3. Preveja quem cobre quem. Recarregue.
Atividades
- Qual valor de
positiontira a caixa do fluxo e ancora nas bordas da janela, mesmo com scroll? - Por que o selo “Vagas fictícias” precisa de
position: relativeno.cartaz? - O skip-link some da tela e volta no Tab. Quais duas propriedades fazem isso?
z-index: 1em umpestático, que não é item de Flexbox nem de Grid, muda a pilha? Explique.- Como centralizar um
h1absoluto na horizontal sem saber a largura do texto?
Respostas comentadas
fixed.absolutesai do fluxo, mas ancora no ancestral posicionado, não na janela.- Sem um ancestral que estabeleça a referência,
absoluteusa o bloco inicial. O selo iria para o canto da página. position: absolutecomleftnegativo esconde.:focusdevolveleftetopvisíveis, comz-indexalto.- Não nesse caso. Em uma caixa comum, use uma posição diferente de
static, comorelative. Itens de Flexbox ou Grid são uma exceção: podem usarz-indexmesmo composition: static. left: 50%etransform: translateX(-50%).
Referências
O arquivo completo
Referência do exemplo 27-position-z-index, reproduzida aqui para que você possa conferir sem sair da página.
assets/javascript/simulacao.js
const form=document.querySelector("#simulacao");if(form){form.querySelector("button[type=submit]").disabled=false;form.addEventListener("submit",event=>{event.preventDefault();document.querySelector("#retorno").textContent="Simulação concluída. Nada foi enviado ou guardado.";});}