Alla fine di questa lezione avrai finalmente capito position — static, relative, absolute, fixed e sticky — non come cinque parole di vocabolario, ma come cinque comportamenti prevedibili che scegli di proposito. Quando scatta, costruisci layout più puliti e sistemi i problemi di allineamento prima che diventino problemi.
Il positioning sembra semplice e poi confonde tutti, prima o poi: gli offset non fanno quel che ti aspetti, un elemento sparisce, o uno sticky si rifiuta di attaccarsi. Il trucco è che ogni valore risponde a due domande — sono ancora nel flusso normale? e rispetto a cosa si misurano i miei offset?. Chiarisci queste due per ciascun valore e l’intera proprietà smette di essere un mistero.
Le vediamo tutte e cinque con lo stesso set minimo — una card con un badge dentro — così vedi esattamente cosa cambia quando giri una sola proprietà.
Come funziona
Static è il default. Significa “lasciami stare, faccio parte del flusso normale” — un blocco dopo l’altro, niente float, niente sovrapposizioni. Non puoi usare offset su un elemento static, ma puoi comunque spostarlo visivamente con un move transform, e il layout si comporta come se non si fosse mai mosso (le percentuali in un transform sono relative alla dimensione dell’elemento stesso). È l’impostazione che-non-fa-niente, e a volte è esattamente ciò che serve.
Relative sembra identica a static finché non la usi — l’elemento resta nel flusso. Ciò che sblocca sono gli offset (top/right/bottom/left) e lo z-index. Gli offset spostano l’elemento visivamente senza toccare ciò che gli sta intorno, quindi left: 4rem lo fa scivolare mentre i vicini fanno finta che non se ne sia andato. È anche il modo per controllare l’ordine di stacking indipendentemente dall’ordine nel DOM. Ma il vero motivo per cui relative conta arriva dopo: è l’àncora per i figli absolute. (Qui gli offset in percentuale sono relativi al parent — e diventano inaffidabili se il parent non ha altezza definita o usa flex/grid.)
Absolute toglie l’elemento dal flusso — tutto il resto si riprende il suo spazio come se non ci fosse — e lo àncora a un punto di riferimento: il primo antenato con posizione non static. Imposta il parent su relative e un badge absolute con top: 0; left: 0 si aggancia all’angolo della card. Togli quel relative e il badge salta all’antenato posizionato successivo risalendo l’albero, o al body se non ce n’è. Senza alcun offset, resta visivamente dov’era ma smette di influenzare il layout. Gli offset in percentuale sono relativi a quel riferimento (il containing block). È lo strumento per ancorare un elemento a un altro — un badge, un’immagine decorativa nell’angolo di una hero, un tooltip.
Fixed esce anch’esso dal flusso, ma ecco la differenza chiave: si àncora sempre al viewport, qualunque cosa facciano gli antenati. Dai al badge top: 0; right: 0 e si aggancia all’angolo dello schermo e resta lì mentre scrolli. Le percentuali sono relative al viewport. Un’insidia da conoscere: un elemento fixed appartiene comunque allo stacking context della sezione in cui vive, quindi sezioni successive con il loro z-index possono coprirlo — la soluzione è alzare lo z-index della sezione parent, non dell’elemento. L’uso classico è una navbar fixed (es. position: fixed; top: 1rem; left: 1rem; width: calc(100% - 2rem) per tenerla ben rientrata da entrambi i bordi).
Sticky è l’ibrido — relative finché non si raggiunge una soglia di scroll, poi fixed. Applicalo con un top: 0 e non succede nulla finché il bordo superiore dell’elemento non raggiunge la cima del container scrollabile; a quel punto si blocca lì e ci resta finché il suo parent non finisce, momento in cui si stacca. Funziona su ogni lato (sticky-top, sticky-bottom e persino sticky-left dentro un container scrollabile in orizzontale), e i suoi offset si misurano rispetto all’antenato scrollabile più vicino. L’insidia grossa: sticky si rompe se un antenato ha overflow diverso da visible o clip (auto, scroll o hidden lo uccidono tutti), perché non riesce più a misurare il flusso che gli serve. Se uno sticky non si attacca, controlla prima i parent.
Come si usa
- Ancora un badge all’angolo di una card. Dai alla card
position: relative, al badgeposition: absolute, poi scegli un angolo (es.top: 0; left: 0, o il preset bottom-left di Webflow). Il badge sta esattamente dove vuoi e non disturba mai il testo della card. - Costruisci una navbar fixed. Imposta la navbar su
position: fixed,top: 1rem,left: 1remewidth: calc(100% - 2rem). L’offsetleftpiù la width incalclasciano uguale respiro su entrambi i lati mentre resta agganciata in alto. - Tieni la UI fixed visibile tra le sezioni. Se il tuo bottone o badge fluttuante sparisce oltre la prima sezione, alza lo
z-indexdella sua sezione parent (non solo dell’elemento) così vince tutto il suo stacking context. - Fissa un indice (table of contents). In una grid a due colonne, imposta il TOC su
position: sticky; top: 150px. Se non si attacca, cambia l’allineamento verticale della grid su top così il TOC prende solo l’altezza che gli serve e ha spazio per muoversi. - Tieni visibile la prima colonna di una tabella scrollabile. In una riga flex che va in overflow orizzontale, dai alla prima colonna
position: sticky; left: 0— resta bloccata a sinistra mentre il resto scorre. - Aggiungi un footer che si rivela. Imposta il footer su
position: sticky; bottom: 0. Quella singola proprietà ti dà l’effetto “footer che appare allo scroll” senza interazioni né codice. - Quando qualcosa non va, controlla due cose: l’
overflowdi un antenato sta rompendo il tuo sticky, e il tuoz-indexsta combattendo uno stacking context che non avevi notato?
Inchioda queste cinque e il positioning smette di essere a tentoni. Ogni valore è solo una risposta chiara a “nel flusso o no?” e “misurato rispetto a cosa?” — e quando conosci entrambe, puoi mettere qualsiasi cosa, ovunque, di proposito.