¿Alguna vez has configurado z-index: 99999 en un elemento de tu CSS y no aparece encima de otros elementos? Un valor tan grande debería colocar fácilmente ese elemento visualmente encima de cualquier otra cosa, asumiendo que todos los elementos diferentes están establecidos en un valor más bajo o no están establecidos en absoluto. Una página web suele representarse en un espacio bidimensional; sin embargo, al aplicar propiedades CSS específicas, se introduce un plano imaginario del eje z para transmitir profundidad. Este plano es perpendicular a la pantalla, y desde él el usuario percibe el orden de los elementos, uno encima del otro. La idea detrás del eje z imaginario, la percepción que tiene el usuario de los elementos apilados, es que las propiedades CSS que lo crean se combinan para formar lo que llamamos un contexto de apilamiento. Vamos a hablar sobre cómo se "apilan" los elementos en una página web, qué controla el orden de apilamiento y enfoques prácticos para "desapilar" elementos cuando sea necesario. Acerca del apilamiento de contextos Imagine su página web como un escritorio. A medida que agrega elementos HTML, coloca pedazos de papel, uno tras otro, sobre el escritorio. La última hoja de papel colocada equivale al elemento HTML agregado más recientemente y se ubica encima de todos los demás papeles colocados antes. Este es el flujo de documentos normal, incluso para elementos anidados. El escritorio en sí representa el contexto de apilamiento raíz, formado por el elemento , que contiene todas las demás carpetas. Ahora entran en juego propiedades CSS específicas. Propiedades como posición (con índice z), opacidad, transformación y contenido) actúan como una carpeta. Esta carpeta toma un elemento y todos sus elementos secundarios, los extrae de la pila principal y los agrupa en una subpila separada, creando lo que llamamos un contexto de apilamiento. Para elementos posicionados, esto sucede cuando declaramos un valor de índice z distinto de auto. Para propiedades como opacidad, transformación y filtro, el contexto de apilamiento se crea automáticamente cuando se aplican valores específicos.
Intente comprender esto: una vez que una hoja de papel (es decir, un elemento secundario) está dentro de una carpeta (es decir, el contexto de apilamiento principal), nunca podrá salir de esa carpeta ni colocarse entre papeles en una carpeta diferente. Su índice z ahora sólo es relevante dentro de su propia carpeta.
En la siguiente ilustración, el Papel B ahora está dentro del contexto de apilamiento de la Carpeta B y solo se puede pedir con otros papeles en la carpeta.
Imagine, por así decirlo, que tiene dos carpetas en su escritorio:
.carpeta-a { índice z: 1; } .carpeta-b { índice z: 2; }
Actualicemos un poco el marcado. Dentro de la carpeta A hay una página especial, índice z: 9999. Dentro de la carpeta B hay una página simple, índice z: 5.
.página especial { índice z: 9999; } .página simple { índice z: 5; }
¿Qué página está en la parte superior? Es la página .plain en la Carpeta B. El navegador ignora los documentos secundarios y apila las dos carpetas primero. Ve la Carpeta B (índice z: 2) y la coloca encima de la Carpeta A (índice z: 1) porque sabemos que dos es mayor que uno. Mientras tanto, la página .special-page configurada en z-index: 9999 está en la parte inferior de la pila aunque su índice z esté configurado en el valor más alto posible. Los contextos de apilamiento también se pueden anidar (carpetas dentro de carpetas), creando un "árbol genealógico". Se aplica el mismo principio: un niño nunca puede escapar de la carpeta de sus padres. Ahora que comprende cómo se comportan los contextos de apilamiento como carpetas que agrupan y reordenan capas, vale la pena preguntarse: ¿por qué ciertas propiedades, como transformación y opacidad, crean nuevos contextos de apilamiento? Aquí está la cuestión: estas propiedades no crean contextos de apilamiento debido a su apariencia; lo hacen por cómo funciona el navegador bajo el capó. Cuando aplicas transformación, opacidad, filtro o perspectiva, le estás diciendo al navegador: "Oye, este elemento puede moverse, rotar o desvanecerse, ¡así que prepárate!".
Cuando utiliza estas propiedades, el navegador crea un nuevo contexto de apilamiento para administrar la representación de manera más eficiente. Esto permite que el navegador maneje animaciones, transformaciones y efectos visuales de forma independiente, lo que reduce la necesidad de volver a calcular cómo estos elementos interactúan con el resto de la página. Piense en ello como si el navegador dijera: "Manejaré esta carpeta por separado para no tener que reorganizar todo el escritorio cada vez que algo dentro cambie". Pero hayun efecto secundario. Una vez que el navegador eleva un elemento a su propia capa, debe "aplanar" todo lo que contiene, creando un nuevo contexto de apilamiento. Es como sacar una carpeta del escritorio para manipularla por separado; todo lo que hay dentro de esa carpeta se agrupa y el navegador ahora lo trata como una sola unidad al decidir qué se coloca encima de qué. Entonces, aunque las propiedades de transformación y opacidad no parezcan afectar la forma en que los elementos se apilan visualmente, sí lo hacen, y es para optimizar el rendimiento. Varias otras propiedades CSS también pueden crear contextos de apilamiento por razones similares. MDN proporciona una lista completa si desea profundizar más. Hay bastantes, lo que sólo ilustra lo fácil que es crear inadvertidamente un contexto de apilamiento sin saberlo. El problema del “desapilamiento” Los problemas de apilamiento pueden surgir por muchas razones, pero algunas son más comunes que otras. Los componentes modales son un patrón clásico porque requieren alternar el componente para "abrirlo" en una capa superior sobre todos los demás elementos y luego eliminarlo de la capa superior cuando esté "cerrado". Estoy bastante seguro de que todos nos hemos encontrado con una situación en la que abrimos un modal y, por alguna razón, no aparece. No es que no se haya abierto correctamente, sino que está fuera de la vista en una capa inferior del contexto de apilamiento. Esto te deja preguntándote "¿cómo es posible?" desde que configuraste:
.superposición { posición: fija; /* crea el contexto de apilamiento */ índice z: 1; /* coloca el elemento en una capa encima de todo lo demás */ recuadro: 0; ancho: 100%; altura: 100vh; desbordamiento: oculto; color de fondo: #00000080; }
Esto parece correcto, pero si el elemento principal que contiene el activador modal es un elemento secundario dentro de otro elemento principal que también está configurado en índice z: 1, eso técnicamente coloca el modal en una subcapa oculta por la carpeta principal. Veamos ese escenario específico y un par de otros errores comunes del contexto de apilamiento. Creo que verá no sólo lo fácil que es crear contextos de apilamiento sin darse cuenta, sino también cómo administrarlos mal. Además, la forma de regresar a un estado administrado depende de la situación. Escenario 1: El modal atrapado
Puede ver inmediatamente su modal atrapado en una capa de bajo nivel e identificar al padre. Extensiones del navegador Los desarrolladores inteligentes han creado extensiones para ayudar. Herramientas como esta extensión de Chrome "Inspector de contexto de apilamiento CSS" agregan una pestaña de índice z adicional a sus DevTools para mostrarle información sobre los elementos que crean un contexto de apilamiento.
Extensiones IDE Incluso puedes detectar problemas durante el desarrollo con una extensión como esta para VS Code, que resalta posibles problemas de contexto de apilamiento directamente en tu editor.
Desapilar y recuperar el control Una vez que hayamos identificado la causa raíz, el siguiente paso es abordarla. Hay varios enfoques que puede adoptar para abordar este problema y los enumeraré en orden. Sin embargo, puedes elegir a cualquiera en cualquier nivel; nadie puede quejarse ni obstaculizar a otro. Cambiar la estructura HTML Esta se considera la solución óptima. Para que te encuentres con un problema de contexto de apilamiento, debes haber colocado algunos elementos en posiciones extrañas dentro de tu HTML. Reestructurar la página le ayudará a remodelar el DOM y eliminar el problema del contexto de apilamiento. Encuentre el elemento problemático y elimínelo del elemento de captura en el marcado HTML. Por ejemplo, podemos resolver el primer escenario, "El modal atrapado", moviendo el contenedor .modal fuera del encabezado y colocándolo solo en el elemento
.Este contenido tiene un índice z de 2 y aún no cubrirá el modal.Encabezado
Contenido principal
Cuando haces clic en el botón "Abrir modal", el modal se coloca delante de todo lo demás como se supone que debe estar. Vea el escenario de pluma 1: El modal atrapado (solución) [bifurcado] de Shoyombo Gabriel Ayomide. Ajustar elContexto de apilamiento principal en CSS ¿Qué pasa si el elemento es uno que no puedes mover sin romper el diseño? Es mejor abordar el tema: los padres establecen el contexto. Busque la propiedad (o propiedades) CSS responsable de activar el contexto y elimínela. Si tiene un propósito y no se puede eliminar, asigne al padre un valor de índice z más alto que el de sus elementos hermanos para levantar todo el contenedor. Con un valor de índice z más alto, el contenedor principal se mueve hacia la parte superior y sus hijos aparecen más cerca del usuario. Según lo que aprendimos en el escenario "El menú desplegable sumergido", no podemos mover el menú desplegable fuera de la barra de navegación; no tendría sentido. Sin embargo, podemos aumentar el valor del índice z del contenedor .navbar para que sea mayor que el valor del índice z del elemento .content. .barra de navegación { antecedentes: #333; /* índice z: 1; */ índice z: 3; posición: relativa; }
Con este cambio, el menú desplegable ahora aparece delante del contenido sin ningún problema.
Vea el escenario de pluma 2: El menú desplegable sumergido (solución) [bifurcado] de Shoyombo Gabriel Ayomide.
Pruebe los portales, si utiliza un marco
En marcos como React o Vue, un Portal es una característica que le permite representar un componente fuera de su jerarquía principal normal en el DOM. Los portales son como un dispositivo de teletransportación para sus componentes. Le permiten representar el HTML de un componente en cualquier parte del documento (generalmente directamente en document.body) mientras lo mantienen conectado lógicamente a su padre original para accesorios, estado y eventos. Esto es perfecto para escapar de las trampas de contexto de apilamiento, ya que la salida renderizada aparece literalmente fuera del contenedor principal problemático.
ReactDOM.createPortal(
Esto garantiza que el contenido desplegable no esté oculto detrás de su padre, incluso si el padre tiene un desbordamiento: oculto o un índice z más bajo. En el escenario "La información sobre herramientas recortada" que vimos anteriormente, utilicé un Portal para rescatar la información sobre herramientas del desbordamiento: clip oculto colocándolo en el cuerpo del documento y posicionándolo encima del disparador dentro del contenedor. Consulte el escenario 3 del lápiz: la información sobre herramientas recortada (solución) [bifurcada] de Shoyombo Gabriel Ayomide. Presentamos el contexto de apilamiento sin efectos secundarios Todos los enfoques explicados en la sección anterior tienen como objetivo "desapilar" elementos de contextos de apilamiento problemáticos, pero hay algunas situaciones en las que realmente necesitarás o querrás crear un contexto de apilamiento. Crear un nuevo contexto de apilamiento es fácil, pero todos los enfoques tienen un efecto secundario. Es decir, excepto por el uso de aislamiento: aislar. Cuando se aplica a un elemento, el contexto de apilamiento de los hijos de ese elemento se determina en relación con cada hijo y dentro de ese contexto, en lugar de verse influenciado por elementos externos a él. Un ejemplo clásico es asignar a ese elemento un valor negativo, como índice z: -1. Imagina que tienes un componente .card. Desea agregar una forma decorativa que se encuentre detrás del texto de la tarjeta, pero encima del fondo de la tarjeta. Sin un contexto de apilamiento en la tarjeta, z-index: -1 envía la forma a la parte inferior del contexto de apilamiento raíz (la página completa). Esto hace que desaparezca detrás del fondo blanco de la tarjeta: Vea el índice z negativo de la pluma (problema) [bifurcado] de Shoyombo Gabriel Ayomide. Para resolver esto, declaramos aislamiento: aislar en la tarjeta principal: Vea el índice z Pen Negative (solución) [bifurcado] de Shoyombo Gabriel Ayomide. Ahora, el elemento .card se convierte en un contexto de apilamiento. Cuando su elemento hijo, la forma decorativa creada en el pseudoelemento :before, tiene índice z: -1, va al final del contexto de apilamiento del padre. Se asienta perfectamente detrás del texto y encima del fondo de la tarjeta, como se esperaba. Conclusión Recuerde: la próxima vez que su índice z parezca estar fuera de control, será un contexto de apilamiento atrapado. Referencias
Contexto de apilamiento (MDN) Índice Z y contextos de apilamiento (web.dev) “Cómo crear un nuevo contexto de apilamiento con la propiedad de aislamiento en CSS”, Natalie Pina "¿Qué diablos, índice z?", Josh Comeau
Lecturas adicionales sobre SmashingMag
"Gestión del índice Z CSS en proyectos grandes", Steven Frieson "Encabezados adhesivos y elementos de altura completa: una combinación complicada", Philip Braunen “Gestión del índice Z en una aplicación web basada en componentes”, Pavel Pomerantsev “La propiedad CSS Z-Index: una mirada integral”, Louis Lazaris