position: absolute em um exemplo
Um elemento com posição absoluta é tirado do fluxo normal e posicionado com top, right, bottom e left. Esses deslocamentos são medidos a partir do ancestral mais próximo que tem um position diferente de static, e é por isso que o pai recebe position: relative:
Apague position: relative de .card e o badge pula para o canto superior direito da página inteira, porque não tem mais um ancestral posicionado. Essa única linha explica a maioria das dúvidas de "position absolute não funciona".
O que saber sobre elementos absolute:
- Eles não ocupam espaço. O título e o parágrafo são dispostos como se o badge não existisse.
- A largura deles encolhe para caber no conteúdo, a menos que você defina
widthoulefterightjuntos. - Os deslocamentos são medidos até a borda do padding do bloco que o contém, por dentro da borda.
Os cinco valores de position
| Valor | No fluxo? | Deslocamentos medidos a partir de | Uso típico |
|---|---|---|---|
static (padrão) | Sim | Deslocamentos são ignorados | Elementos normais |
relative | Sim, o espaço é mantido | A própria posição normal | Âncora para filhos absolute, pequenos ajustes |
absolute | Não | Ancestral posicionado mais próximo (ou a página) | Badges, tooltips, sobreposições, botões de fechar |
fixed | Não | A viewport | Cabeçalhos, botões de chat, barras de cookies |
sticky | Sim | O contêiner de rolagem, ao chegar no deslocamento | Cabeçalhos de tabela, títulos de seção, barras laterais |
position: relative
Um elemento com posição relativa fica onde estava no fluxo. Os deslocamentos mudam onde ele é desenhado, mas o espaço original continua reservado, então nada em volta se move:
A caixa 2 é desenhada 20px para baixo e 20px para a direita, por cima da caixa 3, mas a caixa 3 não se moveu: ela ainda deixa espaço para a caixa 2 no lugar original. Sozinho, o relative raramente é usado para mover coisas; o trabalho principal dele é ser a caixa de referência para filhos absolute.
Deslocamentos e inset
top, right, bottom e left aceitam comprimentos, porcentagens (do bloco que o contém) e auto. O shorthand inset define os quatro na mesma ordem da margin:
.overlay {
position: absolute;
inset: 0; /* top: 0; right: 0; bottom: 0; left: 0; */
}
.corner {
position: absolute;
inset: auto 16px 16px auto; /* bottom right corner, 16px in */
}
Definir lados opostos estica o elemento: left: 0; right: 0 o deixa tão largo quanto o bloco que o contém. inset: 0 em um filho absolute é o jeito padrão de cobrir um card com uma sobreposição.
Centralizar com absolute e transform
top: 50%; left: 50% põe o canto superior esquerdo do elemento no centro. translate(-50%, -50%) o puxa de volta pela metade do próprio tamanho:
Flexbox e grid centralizam de forma mais simples quando o elemento pode ficar no fluxo; a página de como centralizar uma div compara todos os métodos.
position: fixed
Um elemento fixed é posicionado em relação à viewport e fica lá enquanto a página rola:
.chat-button {
position: fixed;
bottom: 16px;
right: 16px;
}
Duas pegadinhas. Um elemento fixed não ocupa espaço, então um cabeçalho fixo cobre o topo da página, a menos que você acrescente padding-top ao body. E se algum ancestral tiver transform, filter ou perspective, esse ancestral vira a caixa de referência no lugar da viewport, e o elemento rola junto com ele.
position: sticky
Um elemento sticky rola normalmente até chegar ao deslocamento e então gruda ali até o fim do pai passar. Role a caixa abaixo:
Cada letra gruda no topo da caixa de rolagem enquanto a seção dela está visível e depois é empurrada pela próxima, porque um elemento sticky nunca sai do pai.
Quando o sticky não gruda, confira:
- Sem deslocamento.
position: stickynão faz nada semtop,bottom,leftouright. - Um ancestral com
overflow: hidden,autoouscroll. Ele vira o contêiner de rolagem, e se ele não rola de fato, nada gruda. Useoverflow: clipse você só precisa esconder o que transborda. - Um pai que não é mais alto que o elemento sticky. Não há espaço para grudar dentro dele.
- Um pai flex ou grid esticando o elemento. Em uma linha flex, acrescente
align-self: flex-startà barra lateral sticky.
Erros comuns
- Esquecer
position: relativeno pai de um elemento absolute. - Usar absolute para o layout da página. Elementos absolute ignoram uns aos outros e o conteúdo, então o texto se sobrepõe em telas menores. Use flexbox ou grid para o layout e absolute para pequenas decorações.
- Deslocamentos em um elemento static.
top: 10pxnão faz nada sem umposition. - Brigar para decidir qual elemento fica por cima. Elementos posicionados que se sobrepõem são ordenados pelo z-index.
- Um cabeçalho fixo escondendo o conteúdo. Acrescente padding à página, ou
scroll-padding-toppara os links de âncora pararem abaixo dele.
Perguntas frequentes
O que position: absolute faz?
Tira o elemento do fluxo normal (os outros elementos agem como se ele não existisse) e o posiciona com top, right, bottom e left, medidos a partir do bloco que o contém: o ancestral mais próximo cujo position não é static.
Como posicionar um elemento absolute em relação ao pai?
Dê ao pai position: relative; e ao filho position: absolute; com deslocamentos como top: 0; right: 0;. Sem um pai posicionado, o filho é posicionado em relação à página.
Qual a diferença entre position relative e absolute?
relative mantém o elemento no fluxo e só muda onde ele é desenhado, deixando o espaço original reservado. absolute o tira do fluxo e o posiciona em relação ao ancestral posicionado.
Por que position: sticky não funciona?
Normalmente é uma de três coisas: nenhum top (ou outro deslocamento) foi definido, um ancestral tem overflow: hidden ou auto e vira o contêiner de rolagem, ou o pai do elemento sticky não é mais alto que ele, então não há espaço para grudar.
Qual a diferença entre fixed e sticky?
fixed sai do fluxo e fica preso à viewport (a menos que um ancestral tenha transform ou filter). sticky fica no fluxo e rola normalmente até chegar ao deslocamento, depois gruda enquanto o pai ainda está na tela.