In Chrome 22 il comportamento del layout degli elementi position:fixed
è leggermente diverso rispetto alle versioni precedenti. Tutti gli elementi position:fixed
ora formano nuovi contesti di impilamento. In questo modo, verrà modificato l'ordine di impilaggio di alcune pagine, il che potrebbe causare la rottura dei layout delle pagine. Il nuovo comportamento corrisponde a quello dei browser WebKit sui dispositivi mobili (Safari per iOS e Chrome per Android).
Che cos'è l'impilamento?
Tutti conoscono e amano l'attributo z-index
per determinare l'ordine di profondità degli elementi in una pagina. Tuttavia, non tutti gli indici z sono uguali: l'z-index
di un elemento determina solo il suo ordinamento rispetto ad altri elementi nello stesso contesto di impilazione. La maggior parte degli elementi di una pagina si trova in un unico contesto di impilamento principale, ma gli elementi posizionati in modo assoluto o relativo con valori z-index
non automatici formano i propri contesti di impilamento (ovvero tutti i relativi elementi secondari saranno ordinati in base all'asse Z all'interno dell'elemento principale e non saranno interlacciati con i contenuti esterni all'elemento principale). A partire da Chrome 22, anche gli elementi position:fixed
creeranno i propri contesti di impilamento.
Per una panoramica generale dei contesti di accodamento, questo articolo di MDN è un'ottima lettura.
Confronta position:fixed
con l'attributo new position:sticky: come riferimento, position:sticky
crea sempre un nuovo contesto di impilamento.
Motivazione
I browser mobile (Safari mobile, browser Android, browser basati su Qt) inseriscono gli elementi position:fixed nei propri contesti di impilamento e lo fanno da un po' di tempo (da iOS 5, Android Gingerbread e così via) perché consente determinate ottimizzazioni dello scorrimento, rendendo le pagine web molto più sensibili al tocco. La modifica viene introdotta su computer per tre motivi:
- Un comportamento di rendering diverso sui browser "mobile" e "desktop" è un ostacolo per gli autori web. Se possibile, il CSS dovrebbe funzionare allo stesso modo ovunque.
- Per i tablet non è chiaro quale degli algoritmi di creazione del contesto di impilamento "dispositivo mobile" o "computer" sia più appropriato.
- Trasferire le ottimizzazioni del rendimento dello scorrimento dai dispositivi mobili ai computer è utile sia per gli utenti che per gli autori.
Dettagli della modifica
Ecco un esempio che mostra i diversi comportamenti di layout: https://codepen.io/paulirish/pen/CgAof
Con la modifica, entrambe le versioni verranno visualizzate come quella a destra.
In questo esempio, il riquadro verde contiene un z-index: 1
, il riquadro rosa un z-index: 3
e il riquadro arancione un z-index: 2
. La casella blu è un'antenata della casella arancione e ha position:fixed
.
Se la casella blu ha un proprio contesto di impilaggio, z-index
della casella arancione viene calcolato in base al contesto di impilaggio della casella blu. Poiché la casella blu ha un z-index
di auto
, il che le conferisce un livello di impilamento pari a zero nel contesto di impilamento principale, la casella arancione si trova dietro le caselle verde e rosa, che hanno indici z di 1 e 3 (rispettivamente) nel contesto principale.
Se la casella blu non ha un proprio contesto di impilamento, z-index
della casella arancione viene calcolato in base al contesto di impilamento principale (insieme alle caselle verdi e rosa). Di conseguenza, la casella arancione viene interlacciata con le caselle rosa e verde.
Per ulteriori dettagli sui criteri per la creazione di contesti in pila (e sul comportamento dei contesti in pila in generale), consulta di nuovo questo articolo MDN. Nell'esempio, la versione a destra assegnava sempre alla casella blu il proprio contesto di impilamento perché la sua opacità è inferiore a 1. La modifica del comportamento apportata aggiunge effettivamente un altro criterio per la creazione di un contesto di impilamento separato, ovvero un elemento con posizione:fissa.
Test e futuro
Per verificare se la tua pagina cambierà, vai a about:flags
di Chrome e attiva/disattiva "Gli elementi con posizione fissa creano contesti di impilamento". Se il layout si comporta allo stesso modo in entrambi i casi, non devi fare altro. In caso contrario, assicurati che il comportamento sia accettabile con il flag attivato, poiché sarà l'impostazione predefinita in Chrome 22.
Questa modifica rimuove una funzionalità, ovvero la possibilità di intercalare contenuti all'interno di un sottoalbero position:fixed con contenuti non scorrevoli esterni. È improbabile che gli sviluppatori web lo facciano intenzionalmente e lo stesso effetto può essere creato assegnando più elementi position:fixed alle diverse parti del DOM. Ad esempio, considera questi due esempi:
https://codepen.io/wiltzius/pen/gcjCk
Questa pagina tenta di prendere due elementi div secondari (overlayA e overlayB) di un elemento position:fixed e di posizionarne uno sopra un elemento div dei contenuti separato e uno sotto lo stesso elemento div dei contenuti separato. Ora è impossibile farlo perché l'elemento position:fixed è il proprio contesto di impilamento e, insieme a tutti i suoi elementi secondari, sarà completamente sopra o completamente sotto l'elemento div dei contenuti. Tieni presente che questo esempio funziona in Chrome 21 e versioni precedenti, ma non più in Chrome 22.
Per risolvere il problema, i due overlay possono essere suddivisi in elementi position:fixed. Ognuno ha il proprio contesto di impilamento, uno dei quali può essere posizionato sopra il div dei contenuti e l'altro sotto. Guarda l'esempio corretto, che funziona in Chrome 21 e 22:
https://codepen.io/wiltzius/pen/vhFzG
Il merito della genesi di questo esempio va all'inimitabile hixie.
Chrome è il primo browser desktop che consente agli elementi position:fixed di creare i propri contesti di impilamento. Lo standard pertinente è la specifica dell'indice z CSS (vedi ad es. https://www.w3.org/TR/CSS21/zindex.html). Non c'è ancora un consenso su cosa fare in merito alla differenza tra i browser mobile e desktop, ma data la confusione derivante da due comportamenti diversi su mobile e desktop, per il momento Chrome ha scelto di passare a questo singolo comportamento su entrambe le piattaforme.
Aggiornamento del 1° ottobre 2012: la versione originale di questo articolo suggeriva che la specifica CSS z-index
fosse già stata modificata per riflettere il nuovo comportamento degli elementi con posizione: fixed. Questa informazione non è accurata; è stata discussa nell'elenco di stili www, ma finora non è stata apportata alcuna modifica alla specifica.