Passa un elemento tra static, relative, absolute, fixed e sticky dentro una demo scorrevole. Containing block, inset, risoluzione dei problemi con sticky e centratura spiegati.
La proprietà position sceglie come viene posizionato un elemento. static è il flusso normale. relative lo sposta leggermente mantenendo il suo spazio. absolute lo toglie dal flusso e lo posiziona rispetto all'antenato posizionato più vicino. fixed lo fissa al viewport. sticky scorre normalmente finché non raggiunge una soglia come top: 0, poi resta lì.
I cinque valori
Valore
Nel flusso?
Posizionato rispetto a
Resta nel flusso
Niente, top/left non hanno effetto
Resta nel flusso, il suo spazio originale viene mantenuto
La sua stessa posizione normale
Tolto dal flusso
Il padding box dell'antenato posizionato più vicino
Tolto dal flusso
Il viewport, a meno che un antenato non abbia transform, filter o simili
Resta nel flusso
L'antenato scorrevole più vicino, entro il suo genitore
La demo qui sotto ha un box arancione dentro un'area scorrevole. Cambia il suo valore di position, sposta gli offset, scorri e osserva rispetto a cosa viene misurato. Seguono una guida ai containing block, una checklist per quando sticky non resta fisso e la shorthand inset.
Scegli un valore di position per il box arancione.
Imposta top e left, e attiva o disattiva il genitore posizionato per vedere quale box usa absolute.
Scorri dentro la demo per confrontare fixed e sticky.
Copia il CSS che corrisponde a ciò che vedi.
Metti position: relative su una card, così i figli absolute usano quella card come riferimento. Questo solo schema copre la maggior parte dei layout con badge e overlay.
Preferisci inset: 0 invece di scrivere top, right, bottom e left separatamente.
Un elemento fixed dentro qualsiasi cosa abbia transform, filter, perspective o contain: paint non è più fissato allo schermo. Spostalo alla fine del body, oppure renderizzalo in un portal.
Gli elementi posizionati vengono disegnati sopra quelli static per impostazione predefinita. Ricorri a z-index solo quando due elementi posizionati si sovrappongono.
Domande frequenti
Qual è la differenza tra absolute e relative?
relative sposta visivamente un elemento ma lascia il suo spazio originale nel layout, quindi niente intorno si muove. absolute toglie del tutto l'elemento dal layout, gli elementi vicini chiudono lo spazio, e top o left vengono misurati dall'antenato posizionato più vicino invece che da dove si sarebbe trovato.
Perché position: sticky non funziona?
Le cause più comuni sono un valore top mancante, un antenato con overflow hidden o auto, oppure un genitore che non è più alto dell'elemento sticky. Segui in ordine la checklist di questa pagina; i primi due punti risolvono la maggior parte dei casi.
Rispetto a cosa si posiziona absolute?
Rispetto al suo containing block: il padding box dell'antenato più vicino con un valore di position diverso da static. Valgono anche gli antenati con un transform, un filter o certi valori di contain. Se non ce n'è nessuno, è l'initial containing block, che ha le dimensioni del viewport.
Perché il mio header fixed si muove con la pagina?
Un antenato ha transform, perspective, filter, backdrop-filter, will-change: transform o contain: paint. Ognuno di questi trasforma quell'antenato nel containing block per i discendenti fixed, quindi l'header resta fissato a lui invece che allo schermo.
Cos'è inset in CSS?
Una shorthand per top, right, bottom e left, che segue lo stesso schema da uno a quattro valori di margin. inset: 0 estende un elemento posizionato su tutto il suo containing block. inset-inline e inset-block impostano le coppie per ciascun asse.
Il containing block, in parole semplici
Ogni offset ha bisogno di un rettangolo di riferimento. Per gli elementi static e relative è il content box del genitore. Per absolute è il padding box dell'antenato posizionato più vicino, quindi il padding della card non spinge verso l'interno un figlio absolute.
Per fixed normalmente è il viewport. Questo cambia quando un antenato riceve transform, perspective, filter, backdrop-filter, contain: paint o un valore di will-change corrispondente: l'antenato diventa il riferimento e l'elemento scorre con lui. La demo in questa pagina usa proprio questo meccanismo perché il suo box fixed resti dentro il riquadro della demo.
Centrare con il posizionamento absolute
Con una dimensione nota, inset: 0 più margin: auto mette il box esattamente al centro e mantiene nitidi i bordi in pixel. Con una dimensione sconosciuta, top: 50% e left: 50% seguiti da translate(-50%, -50%) funzionano con qualsiasi contenuto.
Entrambi tolgono il box dal flusso, quindi il genitore non si allarga attorno a lui. Se il genitore deve adattarsi al contenuto, usa invece la centratura con grid o flex.
Ogni valore nel dettaglio
Valori di position
Valore
Flusso
Cosa fanno gli offset
Uso tipico
Resta nel flusso
Ignorati
Il valore predefinito. Tutto parte da qui.
Resta nel flusso, il suo spazio originale viene mantenuto
Lo spostano rispetto a dove si troverebbe
Piccoli spostamenti, e come ancora per i figli absolute.
Tolto dal flusso
Lo posizionano dentro il containing block
Badge, overlay, menu a tendina, tooltip.
Tolto dal flusso
Lo posizionano sullo schermo
Banner dei cookie, pulsanti flottanti, modali a schermo intero.
Resta nel flusso
Soglia da cui inizia a restare fisso
Intestazioni di tabella, titoli di sezione, menu laterali.
Cosa crea un containing block per absolute e fixed
Antenati che catturano i discendenti posizionati (secondo MDN)
L'antenato ha
I figli absolute lo usano?
I figli fixed lo usano?
position: relative, absolute, fixed o sticky
Sì
No
transform, perspective, rotate, scale o translate diversi da none
Sì
Sì
filter o backdrop-filter diversi da none
Sì
Sì
contain: layout, paint, strict o content
Sì
Sì
will-change che nomina una di quelle proprietà, come transform o filter
Sì
Sì
content-visibility: auto
Sì
Sì
Schemi che userai
Badge nell'angolo di una card
La card è l'antenato posizionato. Gli offset negativi spingono il badge per metà fuori dall'angolo.
Intestazione di tabella sticky
Il contenitore scorre, quindi th con top: 0 resta fisso al suo interno. Lo sfondo evita che le righe si vedano attraverso.
Shorthand inset
Stesso schema di margin: un valore per tutti i lati, due per verticale e orizzontale, quattro in senso orario a partire dall'alto.
Hai impostato una soglia: top, bottom, left o right. Senza, sticky si comporta come relative.
Nessun antenato tra l'elemento e il contenitore che scorre ha overflow: hidden, auto o scroll. Ognuno di questi diventa il contenitore di scorrimento, spesso uno che non scorre mai. overflow: clip non crea un contenitore di scorrimento.
Il genitore è più alto dell'elemento sticky. Resta fisso solo finché il genitore è sullo schermo, poi se ne va insieme a lui.
In una riga flex o grid, l'elemento non è allungato a tutta altezza. Aggiungi align-self: start così ha spazio per muoversi.
L'elemento sticky sta sopra i contenuti che scorrono sotto di lui. Dagli uno sfondo e uno z-index se i contenuti si vedono attraverso.
Lo scorrimento avviene davvero sull'antenato che pensi. Controlla nei DevTools quale elemento ha la barra di scorrimento.
Playground di position
Valore di position
Il genitore ha position: relative
Gli offset vengono ignorati. Il box sta nel flusso normale tra i paragrafi.
Il box è disegnato spostato, ma lo spazio dove si troverebbe viene mantenuto. Gli elementi vicini non si muovono.
Misurato dal genitore tratteggiato, che ha position: relative.
Nessun genitore posizionato, quindi viene misurato dall'area scorrevole della demo, il primo antenato posizionato più in alto.
Fissato al riquadro della demo mentre scorri. Il riquadro ha un transform, che lo rende il containing block al posto della finestra del browser.
Scorre con il testo finché non si trova a top pixel dal bordo superiore del contenitore che scorre, poi resta lì finché il suo genitore non esce dalla vista.
Area demo scorrevole
Scorri dentro questo riquadro. Il testo è di riempimento, così c'è qualcosa da scorrere.
Genitore
Primo paragrafo prima del box.
Paragrafo dopo il box. Osserva se sale quando il box esce dal flusso.
Riga {n} di contenuto aggiuntivo da scorrere.
Contenuto dopo il genitore, riga {n}.
Copia CSS
Perché fixed resta nel riquadro: il riquadro ha transform: translateZ(0). Qualsiasi transform trasforma un elemento nel containing block per i discendenti fixed. In una pagina reale senza un antenato di questo tipo, fixed si aggancia alla finestra del browser.
Sticky non funziona: checklist
Header sticky nascosto dietro altri contenuti? Vedi