Corso di CSS / position: relative, absolute, fixed e sticky
La proprietà position cambia il modo in cui una casella è posizionata e come partecipa al flusso normale. relative mantiene il suo spazio originale, absolute e fixed escono dal flusso, e sticky combina il posizionamento del flusso normale con un blocco temporaneo vincolato durante lo scorrimento.
Confronta le modalità di posizionamento con static
| valore | Spazio originale del flusso normale | Criteri di posizione e scorrimento |
|---|---|---|
| static | mantieni | Flusso generale. Gli offset come top e left non sono applicati |
| relative | mantieni | Sposta tramite un offset dalla posizione originale |
| absolute | non occupato | Di solito il blocco contenitore dell'antenato posizionato più vicino. |
| fixed | non occupato | Viewport normale. Alcune proprietà degli antenati possono modificare i criteri |
| sticky | mantieni | Confini dei meccanismi di scorrimento degli antenati vicini e blocchi contenitori |
Il flusso normale è il layout in cui gli elementi occupano spazio secondo le regole di formattazione del documento. Il testo che segue un elemento posizionato in modo assoluto non si sposta automaticamente per esso. Quando un elemento lascia il flusso, il contenuto successivo può occupare il suo spazio precedente. Evita la sovrapposizione attraverso la struttura del layout o il padding appropriato. Confronta il posizionamento con display: block, inline, inline-block e contenuti nascosti per capire questa differenza.
Gli offset dipendono dalla modalità di posizionamento. Con il posizionamento relativo, top: 16px sposta la casella di 16px verso il basso dalla sua posizione originale. Con il posizionamento assoluto, top misura dal riferimento del containing-block. Lo stesso numero rappresenta quindi relazioni di posizionamento differenti. Vedi MDN: position.
Mantieni lo spazio originale con relative
relative non riposiziona gli altri elementi. Anche se sposti una scheda leggermente verso il basso, la posizione iniziale della scheda successiva rimane invariata. Quindi potrebbe sovrapporsi agli elementi sottostanti o mostrare spazi vuoti sopra. Se lo scopo è cambiare la spaziatura dell'intero documento, verifica prima che margine, padding e gap siano appropriati piuttosto che utilizzare top relativo.
Un altro uso del relativo è creare un riferimento di posizionamento assoluto per i figli. Se scrivi solo position: relative sul genitore e non specifichi un offset, il genitore stesso non si muoverà e diventerà la base per il badge figlio. Specificare una posizione non significa immediatamente che tutti gli elementi si sovrappongano o escano dal flusso del documento.
Trova il blocco contenitore per absolute
Gli elementi assoluti sono solitamente posizionati rispetto al loro antenato più vicino non statico. Se assegni position: relative alla scheda e position: absolute con top e right al figlio, diventa un distintivo all'interno della scheda. Se non c'è un antenato corrispondente, viene utilizzato un criterio più esterno, il che può far spostare il distintivo verso la pagina piuttosto che verso la scheda. Ci sono momenti in cui crei un blocco che include anche proprietà come transform, quindi non dovresti limitarti a trovare la dichiarazione della posizione e fermarti lì.
Un genitore con solo figli assoluti non aggiunge l'altezza dei suoi figli all'altezza del contenuto nel flusso normale. Possono verificarsi problemi in cui il genitore sembra avere altezza zero o i bordi sono collassati, anche se i figli sono visibili. Se il contenuto deve determinare naturalmente l'altezza del genitore, è più facile gestirlo posizionando i figli nel flusso e rendendo assoluti solo i piccoli badge sovrapposti.
Confronta il flusso normale e un badge assoluto
Salva il codice qui sotto come position-flow.html. Le tre sezioni sono composte dall'elemento frontale, dal target e dall'elemento posteriore nello stesso ordine HTML. I 12px del badge della card rappresentano la distanza dall'area standard della card, e il padding superiore è assicurato in modo che non si sovrapponga al corpo della card.
<!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>
- Confronta la posizione del seguente elemento nelle sezioni statica e relativa. Anche se il target relativo viene spostato verso il basso di 16px, lo spazio di posizionamento per l'elemento posteriore viene mantenuto rispetto alla posizione originale del target. Conferma modificando solo il top a 0 e poi ripristinandolo a 16px.
- Una sezione assoluta estrae il target dal flusso e posiziona l'elemento seguente immediatamente dopo l'elemento precedente. Se cambi la posizione di .absolute .target in static, l'altezza del genitore aumenterà dell'altezza del target. Dopo il confronto, ripristina in absolute.
- Prova a eliminare solo position: relative di .card dal badge della card. Dopo aver confermato che il badge non è più ancorato all'angolo in alto a destra della card, ripristinalo immediatamente. Le altre condizioni non cambiano.
- Allunga le lettere sul badge e controlla la spaziatura tra esse e il testo principale. absolute non spinge automaticamente fuori il corpo, quindi se il tuo badge può essere su più righe, dovresti considerare se solo il padding fisso è sufficiente. Dopo la pratica, torna alle lettere originali.
Distinguere fixed e sticky durante lo scorrimento
fixed è solitamente ancorato alla finestra di visualizzazione, mantenendo la sua posizione sullo schermo anche durante lo scorrimento del documento. Può essere utilizzato per piccoli elementi operativi, come il link per tornare in alto, posto in basso a destra dello schermo. Non occupa spazio nel flusso, quindi se hai una barra fissa, assicurati di lasciare abbastanza spazio affinché non oscuri la fine del testo del corpo e l’elemento con focus.
Il transform di un antenato può stabilire il blocco contenitore per un discendente fixed, sostituendo il solito riferimento alla finestra di visualizzazione. Se un elemento fixed si muove con una particolare scatola, ispeziona le proprietà dell'antenato come transform e filter. Questo esempio esclude quelle proprietà per dimostrare il posizionamento sulla finestra di visualizzazione.
Sticky richiede un valore di confine non automatico, come top sull'asse, per osservare l'effetto sticky. Il titolo non è fissato sullo schermo fin dall'inizio, ma rimane nella sua posizione nel flusso e si attacca quando raggiunge il bordo superiore durante lo scorrimento. Quando raggiunge la fine del suo genitore, si muove lungo i suoi limiti e non continua a galleggiare sopra la sezione successiva.
Sticky fa riferimento all’antenato più vicino che crea un meccanismo di scorrimento: possono determinarlo overflow: auto, scroll e anche hidden. Se l'area di scorrimento reale è diversa dall'antenato previsto, oppure l'altezza del contenitore e del titolo sono simili e non c'è spazio per il movimento, il comportamento sticky potrebbe non essere visibile. Piuttosto che rimuovere semplicemente l'overflow, verifica prima quali elementi sono basati sullo scorrimento.
Osservare l'inizio sticky e i limiti del genitore
Salva l'esempio come position-scroll.html. Un'area introduttiva alta almeno 320px mantiene l'intestazione sticky sotto la parte superiore iniziale della finestra di visualizzazione. Il capitolo e la sezione successiva hanno un'altezza sufficiente per osservare quando inizia l'effetto sticky e quando il confine del genitore la rilascia.
<!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>
- Prima di scorrere, assicurati che il titolo sia sotto l'area introduttiva. Abbassalo lentamente in modo che il titolo rimanga fisso quando raggiunge la parte superiore dello schermo. Il link in basso a destra rimane nella stessa posizione dello schermo dall'inizio.
- Scorri attraverso il capitolo e scendi in un'altra area. I titoli sticky vengono spinti fino alla fine del capitolo genitore, ma i link fissi rimangono visibili. Clicca sul link per tornare all'area introduttiva.
- Se modifichi solo la proprietà top di .sticky su auto, non rimarrà alcun offset non-auto sull’asse verticale e scorrerà come un flusso normale. Dopo la conferma, ripristina a 0.
- Aggiungi semplicemente overflow: hidden al tuo .chapter per vedere i risultati sticky nello scorrimento della finestra quando viene modificato l'antenato più vicino con meccanismo di scorrimento. Dopo il confronto, rimuovi la dichiarazione aggiunta.
Diagnostica il posizionamento imprevisto
Se l'ordine di sovrapposizione non cambia nemmeno dopo aver specificato la posizione, controlla z-index CSS e contesti di sovrapposizione.
- Per prima cosa, verifica se c'è spazio disponibile. La disposizione degli elementi circostanti varia a seconda che siano relativi/sticky o assoluti/fissi.
- Controlla la posizione effettiva e i valori applicati top·right·bottom·left negli strumenti per sviluppatori. Controlla anche quali regole e media query hanno la precedenza.
- Per absolute identifica il blocco contenitore; per fixed cerca eventuali proprietà degli antenati che modificano il riferimento abituale al viewport. sticky controlla il confine, l'antenato dello scroll, l'altezza del genitore e il margine di movimento.
- Se le coordinate sono corrette ma sono oscurate, distingui un problema di posizione da un problema di sovrapposizione o di ritaglio dovuto a overflow. Un grande z-index non risolve tutte le occlusioni.




