Algunha vez definiches z-index: 99999 nun elemento do teu CSS e non sae sobre outros elementos? Un valor tan grande debería colocar facilmente ese elemento visualmente encima de calquera outra cousa, asumindo que todos os diferentes elementos estean configurados nun valor inferior ou non se establezan en absoluto. Unha páxina web adoita representarse nun espazo bidimensional; porén, aplicando propiedades específicas de CSS, introdúcese un plano imaxinario do eixe z para transmitir profundidade. Este plano é perpendicular á pantalla, e dende ela, o usuario percibe a orde dos elementos, uns sobre outros. A idea detrás do eixe z imaxinario, a percepción do usuario dos elementos apilados, é que as propiedades CSS que o crean combínanse para formar o que chamamos contexto de apilamiento. Imos falar sobre como se "apilan" os elementos nunha páxina web, o que controla a orde de apilado e enfoques prácticos para "desapilar" os elementos cando sexa necesario. Acerca de apilar contextos Imaxina a túa páxina web como un escritorio. Mentres engades elementos HTML, vas colocando anacos de papel, un tras outro, na mesa. O último anaco de papel colocado é equivalente ao elemento HTML engadido máis recentemente e sitúase encima de todos os demais papeis colocados antes del. Este é o fluxo de documentos normal, mesmo para elementos aniñados. O propio escritorio representa o contexto de apilamiento raíz, formado polo elemento , que contén todos os demais cartafoles. Agora entran en xogo propiedades específicas de CSS. Propiedades como a posición (con índice z), a opacidade, a transformación e o contido) actúan como un cartafol. Este cartafol toma un elemento e todos os seus fillos, extraeos da pila principal e agrúpaos nunha subpila separada, creando o que chamamos contexto de apilamiento. Para elementos posicionados, isto ocorre cando declaramos un valor de índice z distinto de auto. Para propiedades como a opacidade, a transformación e o filtro, o contexto de apilamiento créase automaticamente cando se aplican valores específicos.
Tenta entender isto: unha vez que un anaco de papel (é dicir, un elemento fillo) está dentro dun cartafol (é dicir, o contexto de apilado do pai), nunca poderá saír dese cartafol nin colocarse entre papeis nun cartafol diferente. O seu índice z agora só é relevante dentro do seu propio cartafol.
Na ilustración que aparece a continuación, o papel B está agora no contexto de apilado do cartafol B e só se pode pedir con outros papeis do cartafol.
Imaxina, se queres, que tes dúas carpetas na túa mesa:
.carpeta-a { índice z: 1; } .cartafol-b { índice z: 2; }
Actualicemos un pouco o marcado. Dentro do cartafol A é unha páxina especial, z-index: 9999. Dentro do cartafol B é unha páxina simple, z-index: 5.
.páxina-especial { z-index: 9999; } .páxina simple { z-index: 5; }
Que páxina está enriba? É o .plain-page do cartafol B. O navegador ignora os papeis secundarios e apila os dous cartafoles primeiro. Ve o cartafol B (índice z: 2) e colócao encima do cartafol A (índice z: 1) porque sabemos que dous é maior que un. Mentres tanto, a páxina .special-page definida como z-index: 9999 está na parte inferior da pila aínda que o seu índice z está configurado co valor máis alto posible. Os contextos de apilado tamén se poden aniñar (cartafoles dentro de cartafoles), creando unha "árbore xenealóxica". Aplícase o mesmo principio: un neno nunca pode escapar do cartafol dos seus pais. Agora que entendes como os contextos de apilamiento se comportan como cartafoles que agrupan e reordenan as capas, paga a pena preguntarse: por que certas propiedades, como a transformación e a opacidade, crean novos contextos de apilamiento? Aquí está a cousa: estas propiedades non crean contextos de apilamiento polo seu aspecto; fano por como funciona o navegador baixo o capó. Cando aplicas transformación, opacidade, filtro ou perspectiva, estás dicindo ao navegador: "Oe, este elemento pode moverse, xirar ou esvaecerse, así que prepárate!"
Cando utiliza estas propiedades, o navegador crea un novo contexto de apilamiento para xestionar a renderización de forma máis eficiente. Isto permite que o navegador xestione animacións, transformacións e efectos visuais de forma independente, reducindo a necesidade de recalcular como interactúan estes elementos co resto da páxina. Pense nisto como o navegador dicindo: "Manexarei este cartafol por separado para non ter que reorganizar toda a mesa cada vez que cambie algo no seu interior". Pero haiun efecto secundario. Unha vez que o navegador levanta un elemento na súa propia capa, debe "aplanar" todo o que hai dentro, creando un novo contexto de apilamiento. É como sacar unha carpeta do escritorio para manexala por separado; todo o que hai dentro dese cartafol agrúpase e o navegador agora trátao como unha única unidade cando decide o que se coloca encima de que. Polo tanto, aínda que as propiedades de transformación e opacidade non parecen afectar a forma en que os elementos se apilan visualmente, si, e é para a optimización do rendemento. Varias outras propiedades CSS tamén poden crear contextos de apilamiento por razóns similares. MDN ofrece unha lista completa se queres afondar. Hai bastantes, o que só ilustra o fácil que é crear sen querer un contexto de apilamiento sen sabelo. O problema de "desapilar". Os problemas de acumulación poden xurdir por moitos motivos, pero algúns son máis comúns que outros. Os compoñentes modais son un patrón clásico porque requiren alternar o compoñente para que se "abra" nunha capa superior sobre todos os outros elementos, e despois eliminalo da capa superior cando estea "pechado". Estou bastante seguro de que todos nos atopamos nunha situación na que abrimos un modal e, polo motivo que sexa, non aparece. Non é que non se abrise correctamente, senón que está fóra de vista nunha capa inferior do contexto de apilado. Isto fai que te preguntes "como é que?" xa que estableceches:
.superposición { posición: fixo; /* crea o contexto de apilamiento */ índice z: 1; /* pon o elemento nunha capa por riba de todo */ inserción: 0; ancho: 100%; altura: 100vh; desbordamento: oculto; cor de fondo: #00000080; }
Parece correcto, pero se o elemento principal que contén o disparador modal é un elemento fillo dentro doutro elemento pai que tamén está configurado como índice z: 1, iso técnicamente sitúa o modal nunha subcapa oculta polo cartafol principal. Vexamos ese escenario específico e un par de outras trampas comúns de contexto de apilamiento. Creo que verás non só o fácil que é crear contextos de acumulación sen querer, senón tamén como xestionalos mal. Ademais, a forma de volver a un estado xestionado depende da situación. Escenario 1: o modal atrapado
Podes ver inmediatamente o teu modal atrapado nunha capa de baixo nivel e identificar o pai. Extensións do navegador Os desenvolvedores intelixentes crearon extensións para axudar. Ferramentas como esta extensión de Chrome "CSS Stacking Context Inspector" engaden unha pestana de índice z adicional ás túas DevTools para mostrarche información sobre os elementos que crean un contexto de apilamiento.
Extensións IDE Incluso pode detectar problemas durante o desenvolvemento cunha extensión como esta para VS Code, que destaca os posibles problemas de contexto de acumulación directamente no seu editor.
Desapilar e recuperar o control Despois de identificar a causa raíz, o seguinte paso é tratala. Hai varios enfoques que podes adoptar para solucionar este problema, e enumerareinos por orde. Con todo, podes escoller a calquera en calquera nivel; ninguén pode queixarse nin obstaculizar a outro. Cambiar a estrutura HTML Esta é a solución óptima. Para que teñas un problema de contexto de apilado, debes ter colocado algúns elementos en posicións divertidas dentro do teu HTML. A reestruturación da páxina axudarache a remodelar o DOM e a eliminar o problema do contexto de apilado. Busca o elemento problemático e elimínao do elemento de captura no marcado HTML. Por exemplo, podemos resolver o primeiro escenario, "O modal atrapado", movendo o .modal-container fóra da cabeceira e colocándoo no elemento
por si mesmo.Este contido ten un índice z de 2 e aínda non cubrirá o modal.Cabeceira
Contido principal
Título modal
Agora, non estou detrás de nada. Conseguín unha mellor posición como resultado da reestruturación do DOM.
Cando fai clic no botón "Abrir modal", o modal sitúase diante de todo o demais como se supón que debe ser. Vexa o escenario da pluma 1: o modal atrapado (solución) [bifurcado] de Shoyombo Gabriel Ayomide. Axustar oContexto de apilado dos pais en CSS E se o elemento é un que non podes mover sen romper o deseño? É mellor abordar o tema: o pai establece o contexto. Busca a propiedade (ou propiedades) CSS responsables de activar o contexto e elimínaa. Se ten un propósito e non se pode eliminar, dálle ao pai un valor de índice z superior ao dos seus elementos irmáns para levantar todo o contenedor. Cun valor de índice z máis alto, o contenedor principal móvese á parte superior e os seus fillos aparecen máis preto do usuario. Segundo o que aprendemos no escenario "O menú despregable mergullado", non podemos mover o menú despregable da barra de navegación; non tería sentido. Non obstante, podemos aumentar o valor do índice z do contenedor .navbar para que sexa maior que o valor do índice z do elemento .content. .navbar { fondo: #333; /* índice z: 1; */ índice z: 3; posición: relativo; }
Con este cambio, o menú despregable . agora aparece diante do contido sen ningún problema.
Vexa o escenario Pen 2: The Submerged Dropdown (Solución) [bifurcado] de Shoyombo Gabriel Ayomide.
Proba portais, se usas un marco
En marcos como React ou Vue, un Portal é unha función que che permite renderizar un compoñente fóra da súa xerarquía pai normal no DOM. Os portais son como un dispositivo de teletransportación para os teus compoñentes. Permítenche renderizar o HTML dun compoñente en calquera parte do documento (normalmente directamente en document.body) mentres o manteñen conectado loxicamente ao seu pai orixinal para accesorios, estado e eventos. Isto é perfecto para escapar de trampas de contexto de apilado xa que a saída renderizada aparece literalmente fóra do contenedor principal problemático.
ReactDOM.createPortal(
Isto garante que o contido do menú despregable non estea escondido detrás do seu pai, aínda que este teña un desbordamento: oculto ou un índice z inferior. No escenario "A información sobre ferramentas recortada" que analizamos anteriormente, usei un Portal para rescatar a información sobre ferramentas do desbordamento: clip oculto colocándoo no corpo do documento e colocándoo por riba do gatillo dentro do contedor. Vexa o Escenario 3 do Pen: The Clipped Tooltip (Solución) [forked] de Shoyombo Gabriel Ayomide. Presentación do contexto de apilado sen efectos secundarios Todos os enfoques explicados na sección anterior teñen como obxectivo "desapilar" elementos de contextos de apilamiento problemáticos, pero hai algunhas situacións nas que realmente necesitará ou quere crear un contexto de apilamiento. Crear un novo contexto de acumulación é sinxelo, pero todos os enfoques teñen un efecto secundario. É dicir, agás por usar illamento: illar. Cando se aplica a un elemento, o contexto de apilamiento dos fillos dese elemento determínase en relación con cada fillo e dentro dese contexto, en lugar de estar influenciado por elementos fóra del. Un exemplo clásico é asignarlle a ese elemento un valor negativo, como índice z: -1. Imaxina que tes un compoñente .card. Quere engadir unha forma decorativa que se asenta detrás do texto da tarxeta, pero encima do fondo da tarxeta. Sen un contexto de apilamiento na tarxeta, z-index: -1 envía a forma á parte inferior do contexto de apilamiento raíz (toda a páxina). Isto fai que desapareza detrás do fondo branco do .card: Vexa o índice z negativo da pluma (problema) [bifurcado] de Shoyombo Gabriel Ayomide. Para solucionar isto, declaramos illamento: illar na tarxeta .pai: Vexa o índice z de Pen Negative (solución) [bifurcado] de Shoyombo Gabriel Ayomide. Agora, o propio elemento .card convértese nun contexto de apilamiento. Cando o seu elemento fillo, a forma decorativa creada no pseudoelemento :before, ten índice z: -1, vai ao fondo do contexto de apilamiento do pai. Atópase perfectamente detrás do texto e enriba do fondo da tarxeta, como se pretende. Conclusión Lembra: a próxima vez que o teu índice z pareza fóra de control, é un contexto de apilamiento atrapado. Referencias
Contexto de apilamiento (MDN) Índice Z e contextos de apilamiento (web.dev) "Como crear un novo contexto de apilado coa propiedade de illamento en CSS", Natalie Pina "Que diablos, índice z?", Josh Comeau
Máis lecturas sobre SmashingMag
"Xestionar CSS Z-Index en grandes proxectos", Steven Frieson "Encabezados adhesivos e elementos de altura completa: unha combinación complicada", Philip Braunen "Xestionar Z-Index nunha aplicación web baseada en compoñentes", Pavel Pomerantsev "A propiedade CSS Z-Index: unha mirada completa", Louis Lazaris