Se vienen cambios de apilado en los elementos position:fixed

Tom Wiltzius
Tom Wiltzius

En Chrome 22, el comportamiento del diseño de los elementos position:fixed es ligeramente diferente al de las versiones anteriores. Todos los elementos position:fixed ahora forman nuevos contextos de apilamiento. Esto cambiará el orden de apilamiento de algunas páginas, lo que podría dañar los diseños de página. El nuevo comportamiento coincide con el de los navegadores WebKit en dispositivos móviles (Safari para iOS y Chrome para Android).

¿Qué se puede apilar?

Todo el mundo conoce y ama el z-index para determinar el orden de profundidad de los elementos en una página. Sin embargo, no todos los índices z son iguales: el z-index de un elemento solo determina su orden en relación con otros elementos en el mismo contexto de apilamiento. La mayoría de los elementos de una página se encuentran en un solo contexto de apilamiento raíz, pero los elementos con posición absoluta o relativa con valores de z-index no automáticos forman sus propios contextos de apilamiento (es decir, todos sus elementos secundarios se ordenarán en Z dentro del elemento superior y no se intercalarán con contenido de fuera de él). A partir de Chrome 22, los elementos position:fixed también crearán sus propios contextos de apilamiento.

Para obtener una descripción general de los contextos de apilamiento, este artículo de MDN es una excelente opción.

Compara position:fixed con el atributo new position:sticky: Como referencia, position:sticky siempre crea un nuevo contexto de apilamiento.

Motivación

Los navegadores para dispositivos móviles (Safari para dispositivos móviles, navegador de Android y navegadores basados en Qt) colocan elementos position:fixed en sus propios contextos de apilamiento y lo hacen desde hace tiempo (desde iOS 5, Android Gingerbread, etc.) porque permite ciertas optimizaciones del desplazamiento, lo que hace que las páginas web sean mucho más responsivas al tacto. El cambio se implementará en computadoras por tres motivos:

  1. Tener un comportamiento de renderización diferente en los navegadores "móviles" y "para computadoras" es un obstáculo para los autores web. El CSS debe funcionar de la misma manera en todas partes cuando sea posible.
  2. En el caso de las tablets, no está claro cuál de los algoritmos de creación de contexto de apilamiento "para dispositivos móviles" o "para computadoras de escritorio" es más adecuado.
  3. Llevar las optimizaciones de rendimiento del desplazamiento de los dispositivos móviles a las computadoras de escritorio es beneficioso tanto para los usuarios como para los autores.

Detalles del cambio

A continuación, se muestra un ejemplo de los diferentes comportamientos del diseño: https://codepen.io/paulirish/pen/CgAof

Con el cambio, ambas versiones se renderizarán como la versión de la derecha.

En este ejemplo, el cuadro verde tiene un z-index: 1, el cuadro rosa tiene un z-index: 3 y el cuadro naranja tiene un z-index: 2. El cuadro azul es un ancestro del cuadro naranja y tiene position:fixed.

Si el cuadro azul obtiene su propio contexto de apilamiento, el z-index del cuadro naranja se calcula en relación con el contexto de apilamiento del cuadro azul. Dado que el cuadro azul tiene un z-index de auto, lo que le da un nivel de apilamiento de cero en el contexto de apilamiento raíz, esto significa que el cuadro naranja termina detrás de los cuadros verde y rosa, que tienen índices z de 1 y 3 (respectivamente) en el contexto raíz.

Si el cuadro azul no obtiene su propio contexto de apilamiento, el z-index del cuadro naranja se calcula en relación con el contexto de apilamiento raíz (junto con los cuadros verde y rosa). Por lo tanto, el cuadro naranja termina intercalado con los cuadros rosa y verde.

Para obtener más detalles sobre los criterios para la creación de contextos de apilamiento (y cómo se comportan los contextos de apilamiento en general), consulta este artículo de MDN. En el ejemplo, la versión de la derecha siempre le daba al cuadro azul su propio contexto de apilamiento porque su opacidad es inferior a 1. El cambio de comportamiento que se realiza agrega, de manera efectiva, otro criterio para crear un contexto de apilamiento independiente, es decir, un elemento con position:fixed.

Pruebas y el futuro

Para probar si tu página cambiará, ve a about:flags de Chrome y activa o desactiva "Los elementos de posición fija crean contextos de apilamiento". Si tu diseño se comporta de la misma manera en ambos casos, ya está todo listo. De lo contrario, asegúrate de que te parezca aceptable con esa marca habilitada, ya que esa será la configuración predeterminada en Chrome 22.

Este cambio quita una función: la capacidad de intercalar contenido dentro de un subárbol position:fixed con contenido sin desplazamiento desde el exterior. Es poco probable que algún desarrollador web haga esto a propósito, y se puede crear el mismo efecto si se asignan diferentes posiciones de DOM a varios elementos position:fixed. A modo de ejemplo, considera estos dos ejemplos:

https://codepen.io/wiltzius/pen/gcjCk

Esta página intenta tomar dos divs secundarios (overlayA y overlayB) de un elemento position:fixed y colocar uno sobre una div de contenido independiente y uno debajo de esa misma div de contenido independiente. Ahora es imposible hacerlo porque el elemento position:fixed es su propio contexto de apilamiento y, junto con todos sus elementos secundarios, estará completamente por encima o por debajo de la div de contenido. Ten en cuenta que este ejemplo funciona en Chrome 21 y versiones anteriores, pero ya no en Chrome 22.

Para solucionar este problema, las dos superposiciones se pueden dividir en su propia posición:elementos fijos. Cada uno tiene su propio contexto de apilamiento, uno de los cuales puede ir por encima del div de contenido y el otro por debajo. Consulta el ejemplo corregido, que funciona en Chrome 21 y 22:

https://codepen.io/wiltzius/pen/vhFzG

El crédito por el origen de este ejemplo se debe al inigualable hixie.

Chrome es el primer navegador para computadoras de escritorio que hace que los elementos position:fixed creen sus propios contextos de apilamiento. El estándar relevante es la especificación de índice z del CSS (consulta, por ejemplo, https://www.w3.org/TR/CSS21/zindex.html). Aún no hay consenso sobre qué hacer con la diferencia entre los navegadores para dispositivos móviles y computadoras de escritorio, pero, debido a la confusión que genera tener dos comportamientos diferentes en dispositivos móviles y computadoras, Chrome decidió adoptar este comportamiento único en ambas plataformas por el momento.

Actualización del 1 de octubre de 2012: La versión original de este artículo sugería que la especificación z-index de CSS ya se había modificado para reflejar el nuevo comportamiento de los elementos position: fixed. Esto no es exacto. Se analizó en la lista de estilo www, pero hasta el momento no se realizó ningún cambio en la especificación.