Curso de CSS / position: relative, absolute, fixed e sticky
A propriedade position altera como uma caixa é posicionada e como ela participa do fluxo normal. relative mantém seu espaço original, absolute e fixed saem do fluxo, e sticky combina o posicionamento do fluxo normal com aderência restrita durante o scroll.
Compare os modos de posicionamento com static
| valor | Espaço original do fluxo normal | Critérios de posição e rolagem |
|---|---|---|
| static | manter | Fluxo geral. Deslocamentos como top e left não são aplicados |
| relative | manter | Mover por um deslocamento a partir do local de posicionamento original |
| absolute | não ocupado | Geralmente o bloco contêiner do ancestral posicionado mais próximo. |
| fixed | não ocupado | Viewport normal. Algumas propriedades ancestrais podem mudar o critério |
| sticky | manter | Limites dos ancestrais de mecanismo de rolagem próximos e blocos contêineres |
O fluxo normal é a disposição na qual os elementos ocupam espaço de acordo com as regras de formatação do documento. O texto que segue um elemento posicionado de forma absoluta não se move automaticamente para o lado dele. Quando um elemento sai do fluxo, o conteúdo seguinte pode ocupar seu espaço anterior. Evite sobreposição através da estrutura do layout ou com preenchimento apropriado. Compare o posicionamento com display: block, inline, inline-block e ocultação para entender essa diferença.
Os deslocamentos dependem do modo de posicionamento. Com posicionamento relativo, top: 16px desloca a caixa 16px para baixo a partir de sua posição original. Com posicionamento absoluto, top mede a partir de sua referência de bloco contêiner. Portanto, o mesmo número representa diferentes relações de posicionamento. Veja MDN: position.
Mantenha o espaço original com relative
relative não reposiciona os outros elementos. Mesmo que você mova um cartão um pouco para baixo, a posição inicial do próximo cartão é mantida. Portanto, ele pode sobrepor elementos abaixo ou mostrar espaço vazio acima. Se o objetivo é alterar o espaçamento de todo o documento, primeiro verifique se a margem, o padding e o gap estão apropriados, em vez de usar top relativo.
Outro uso de relative é criar uma referência de posicionamento absoluto para os filhos. Se você apenas escrever position: relative no elemento pai e não especificar um deslocamento, o próprio pai não se moverá e se tornará a base para o badge do filho. Especificar uma posição não significa imediatamente que todos os elementos se sobreponham ou saiam do fluxo do documento.
Encontre o bloco de referência de absolute
Elementos com posição absoluta geralmente são posicionados em relação ao seu ancestral mais próximo que não seja estático. Se você definir position: relative no cartão e position: absolute com top e right no filho, ele se torna um badge dentro do card. Se não houver um ancestral correspondente, um critério mais externo é usado, o que pode fazer o badge se mover em direção à página em vez do card. Há momentos em que você cria um bloco que também inclui propriedades como transform, então você não deve apenas encontrar a declaração de posição e finalizar.
Um pai com apenas filhos absolutos não adiciona a altura de seus filhos à altura do conteúdo no fluxo normal. Problemas em que o pai parece ter altura zero ou as bordas estão colapsadas podem ocorrer mesmo que os filhos estejam visíveis. Se o conteúdo precisar determinar naturalmente a altura do pai, é mais fácil gerenciá-la colocando os filhos no fluxo e tornando apenas os pequenos selos sobrepostos absolutos.
Compare fluxo normal e um selo absoluto
Salve o código abaixo como position-flow.html. As três seções são compostas pelo elemento frontal, alvo e elemento traseiro na mesma ordem HTML. Os 12px do selo do cartão são os deslocamentos a partir das bordas superior e direita da área de referência do cartão, e o preenchimento superior é garantido para que não sobreponha o corpo do cartão.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>position-flow.html</title>
<style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.flow { border: 2px dashed #789; margin-bottom: 40px; margin-right: 24px; }
.flow > div { height: 56px; padding: 12px; background: #e8f5de; }
.flow .target { background: #dceefa; }
.relative .target { position: relative; top: 16px; left: 20px; }
.absolute { position: relative; }
.absolute .target { position: absolute; top: 16px; left: 20px; }
.card { position: relative; padding: 64px 20px 20px; background: #dceefa; max-width: 600px; }
.badge { position: absolute; top: 12px; right: 12px; padding: 4px 12px; background: #ffe4b5; }
</style>
</head>
<body>
<h1>Does the original space remain?</h1>
<h2>static</h2><div class="flow static"><div>Front element</div><div class="target">Target</div><div class="after">Back element</div></div>
<h2>relative</h2><div class="flow relative"><div>Front element</div><div class="target">Target</div><div class="after">Back element</div></div>
<h2>absolute</h2><div class="flow absolute"><div>Front element</div><div class="target">Target</div><div class="after">Back element</div></div>
<h2>Badge inside the card</h2><div class="card"><span class="badge">News</span><p>The badge sits at the top right of the card. Top padding separates it from the text.</p></div>
</body>
</html>
- Compare a posição do elemento seguinte nas seções estática e relativa. Mesmo se o alvo relativo for movido para baixo em 16px, o espaço de colocação para o elemento posterior é mantido em relação à posição original do alvo. Confirme alterando apenas o top para 0 e depois restabeleça para 16px.
- Uma seção absoluta tira o alvo do fluxo e coloca o elemento seguinte imediatamente após o elemento anterior. Se você mudar a posição de .absolute .target para static, a altura do elemento pai aumentará pela altura do alvo. Após a comparação, restaure para absolute.
- Remova temporariamente apenas position: relative de .card do selo do cartão. Depois de confirmar que o selo não está mais ancorado no canto superior direito do cartão, restaure-o imediatamente. Outras condições não mudam.
- Alongue as letras no selo e verifique o espaçamento entre elas e o texto principal. absolute não empurra automaticamente o corpo, então, se o seu selo puder ter várias linhas, você deve considerar se apenas o padding fixo é suficiente. Depois da prática, retorne às letras originais.
Compare fixed e sticky durante a rolagem
fixed geralmente é ancorado à área de visualização, mantendo sua posição na tela mesmo quando o documento é rolado. Pode ser usado para pequenos elementos de operação, como o botão superior no canto inferior direito da tela. Ele não ocupa espaço no fluxo, então se você tiver uma barra fixed, certifique-se de deixar espaço suficiente para que não obscureça o final do texto do corpo e o objeto de foco.
O transform de um ancestral pode estabelecer o bloco contêiner para um descendente fixed, substituindo a referência usual à área de visualização. Se um elemento fixed se move com uma caixa específica, inspecione propriedades dos ancestrais, como transform e filter. Este exemplo exclui essas propriedades para demonstrar o posicionamento na área de visualização.
Sticky requer um valor de limite não automático, como top no eixo, para observar o efeito sticky. O título não fica fixo na tela desde o início, mas permanece em sua posição de fluxo e se fixa quando alcança o limiar superior definido por top durante a rolagem. Quando atinge o final de seu elemento pai, ele se move dentro de seus limites e não continua a flutuar acima da próxima seção.
Sticky é influenciado por seus ancestrais próximos com mecanismo de rolagem. Ancestrais com overflow: auto, scroll ou hidden podem alterar a referência, mesmo quando o ancestral com esse mecanismo não é o elemento que está efetivamente rolando. Se a área de rolagem real for diferente do ancestral esperado, ou a altura do container e do título forem semelhantes e não houver espaço para movimento, a ação de fixação pode não ser visível. Em vez de apenas remover o overflow, primeiro verifique quais elementos têm rolagem.
Observe o início fixo e os limites do elemento pai
Salve o exemplo como position-scroll.html. Uma área de introdução de pelo menos 320px de altura mantém o título fixo abaixo do topo inicial da tela. O capítulo e a seção seguinte têm altura suficiente para observar quando a fixação começa e quando o limite do elemento pai o libera.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>position-scroll.html</title>
<style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
body { margin: 0; padding-bottom: 80px; }
.intro { min-height: 320px; padding: 24px; background: #eef2f6; }
.chapter { min-height: 760px; background: #e8f5de; }
.sticky { position: sticky; top: 0; margin: 0; padding: 16px; background: #dceefa; border-bottom: 2px solid #789; }
.chapter p { padding: 16px; }
.tail { min-height: 900px; padding: 24px; background: #fff2df; }
.fixed { position: fixed; right: 16px; bottom: 16px; padding: 12px; background: #fff; border: 2px solid #145f8f; }
</style>
</head>
<body>
<div class="intro" id="top"><h1>A heading that sticks while scrolling</h1><p>The heading below starts in normal flow. It sticks when it reaches the top of the screen and remains within its parent at the end of the chapter.</p></div>
<section class="chapter"><h2 class="sticky">Chapter heading</h2><p>This content is inside the chapter. The extra height lets you observe how long its heading remains sticky.</p></section>
<section class="tail"><h2>Another section</h2><p>Check whether the previous chapter's heading stays above this section.</p></section>
<a class="fixed" href="#top">Back to top</a>
</body>
</html>
- Antes de rolar, certifique-se de que o título está abaixo da área introdutória. Abaixe-o lentamente para que o título fique fixo quando alcançar o topo da tela. O link superior no canto inferior direito permanece na mesma posição da tela desde o início.
- Role pelo capítulo e vá para outra área. O título sticky fica limitado pelo capítulo pai e sai do topo quando esse limite é alcançado; o link fixed continua na posição da janela. Clique no link para retornar à área introdutória.
- Se você mudar apenas o top de .sticky para auto, não haverá um limiar vertical definido neste exemplo e ele vai rolar como um fluxo normal. Após a confirmação, restaure para 0.
- Basta adicionar overflow: hidden ao seu .chapter para ver os resultados do sticky ao rolar a janela quando o ancestral mais próximo com mecanismo de rolagem for alterado. Após comparar, remova a declaração adicionada.
Diagnostique posicionamento inesperado
Se a ordem de empilhamento não mudar mesmo após especificar a posição, verifique o z-index e contextos de empilhamento.
- Primeiro, verifique se há espaço disponível. O posicionamento dos elementos ao redor varia dependendo se eles são relative/sticky ou absolute/fixed.
- Verifique a posição real e os valores aplicados de top, right, bottom e left nas ferramentas de desenvolvedor. Também verifique quais regras e media queries têm precedência.
- absolute verifica o ancestral base, e fixed verifica a propriedade do ancestral que altera o bloco de contenção. sticky verifica limite, ancestral de rolagem, altura do pai e margem de movimento.
- Se as coordenadas estiverem corretas mas estiverem ocultas, diferencie entre um problema de localização e uma ordem de sobreposição/truncamento de overflow. Um z-index grande não resolve todas as occlusões.




