z-index
Posicionamiento
Controla el orden de apilamiento de los elementos posicionados en el eje Z. Solo tiene efecto en elementos con position distinto de static, y opera dentro de contextos de apilamiento.
z-index es la propiedad CSS que controla el orden de apilamiento de los elementos en el eje Z — el eje perpendicular a la pantalla, el que determina qué queda “encima” y qué queda “debajo” cuando dos elementos se superponen. Un valor mayor significa que el elemento aparece delante; un valor menor lo envía detrás. Acepta enteros positivos, negativos y 0. Sin z-index, el orden de apilamiento lo determina el orden del HTML: el elemento que aparece más tarde en el markup queda encima.
La condición más importante y más frecuentemente olvidada de z-index es que solo tiene efecto en elementos posicionados — es decir, en aquellos con position diferente de static. Declarar z-index: 999 en un elemento position: static no produce ningún efecto en el orden de apilamiento, aunque el valor aparezca en el getComputedStyle. Siempre va acompañado de un position: relative, absolute, fixed o sticky.
El sistema de z-index no es global: los valores se comparan dentro del mismo contexto de apilamiento (stacking context). Un z-index: 9999 dentro de un contexto con z-index: 1 nunca puede superar a un elemento hermano de ese contexto con z-index: 2. Esta jerarquía de contextos es el concepto más malentendido del sistema y la causa de la mayoría de los bugs de apilamiento.
Cómo funciona
El navegador pinta los elementos en un orden determinado. Por defecto, ese orden sigue el flujo del documento: los elementos que aparecen después en el HTML se pintan encima de los anteriores. z-index permite alterar ese orden para los elementos posicionados.
El modelo de apilamiento tiene una jerarquía:
- El fondo e imagen de fondo del elemento raíz.
- Elementos con
z-indexnegativo. - Elementos en flujo normal (bloques e inline) sin z-index.
- Elementos posicionados sin
z-index(o conz-index: auto). - Elementos posicionados con
z-index: 0. - Elementos posicionados con
z-indexpositivo.
.fondo { position: relative; z-index: 1; }
.tarjeta { position: absolute; z-index: 2; } /* encima de .fondo */
.modal { position: fixed; z-index: 100; } /* encima de todo */
Sintaxis
selector {
position: relative; /* o absolute, fixed, sticky — obligatorio */
z-index: 10; /* entero positivo, negativo o 0 */
z-index: auto; /* valor por defecto — no crea contexto propio */
z-index: -1; /* puede quedar debajo del flujo normal */
}
Valores
auto (valor por defecto)
El elemento se apila según el orden del DOM, sin establecer un nivel de apilamiento explícito. Importante: z-index: auto no crea un nuevo contexto de apilamiento. Es diferente de z-index: 0, que sí lo crea.
Enteros positivos
El elemento queda encima de aquellos con valores menores. No existe un máximo oficial, pero en la práctica se usan convenciones de escala (10, 100, 1000) para dejar espacio entre capas y no necesitar reordenar al agregar nuevos elementos.
| Convención de escala | Uso típico |
|---|---|
1 – 10 | Elementos de layout con leve elevación (cards, dropdowns) |
100 – 200 | Barras de navegación, sidebars fijos |
300 – 500 | Modales, overlays |
1000+ | Notificaciones, tooltips globales |
.card { position: relative; z-index: 1; }
.dropdown-menu { position: absolute; z-index: 100; }
.modal-overlay { position: fixed; z-index: 300; }
.toast { position: fixed; z-index: 1000; }
0
El elemento entra en el apilamiento de los posicionados (por encima del flujo normal) pero sin ventaja sobre otros con z-index: 0. A diferencia de auto, sí crea un nuevo contexto de apilamiento.
Enteros negativos
El elemento queda debajo de los elementos en flujo normal. Es útil para efectos visuales donde un pseudo-elemento o un fondo decorativo debe quedar detrás del contenido.
.tarjeta {
position: relative;
}
.tarjeta::before {
content: "";
position: absolute;
inset: 0;
z-index: -1; /* detrás del contenido de .tarjeta */
background: linear-gradient(135deg, #fef3c7, #fbbf24);
border-radius: 8px;
}
Contextos de apilamiento
El concepto central — y el más malentendido — de z-index es el contexto de apilamiento (stacking context). Un contexto de apilamiento es un grupo de elementos que se apilan entre sí de forma independiente del resto de la página. Los z-index se comparan solo dentro del mismo contexto.
Un elemento crea un nuevo contexto de apilamiento cuando:
- Tiene
position≠staticyz-index≠auto(incluyendoz-index: 0). - Tiene
opacity< 1 (veropacity). - Tiene
transform,filter,perspectiveowill-changeaplicados. - Tiene
isolation: isolatedeclarado.
El gotcha principal: si el elemento padre crea un contexto con z-index: 1, ningún hijo puede quedar encima de un elemento hermano del padre con z-index: 2, sin importar qué z-index tenga ese hijo.
/* BUG frecuente */
.contenedor { position: relative; z-index: 1; }
.hijo { position: relative; z-index: 9999; }
/* .hijo NUNCA queda encima de un elemento con z-index: 2 al mismo nivel que .contenedor */
/* SOLUCIÓN: subir el z-index del contenedor, no del hijo */
.contenedor { position: relative; z-index: 10; }
Bloque “Resultado”
Tres cajas superpuestas con distintos valores de z-index:
.capa-base {
position: relative;
z-index: 1;
background: #1d4ed8;
}
.capa-media {
position: absolute;
top: 16px; left: 40px;
z-index: 2;
background: #0d9488;
}
.capa-frente {
position: absolute;
top: 32px; left: 80px;
z-index: 3;
background: #b45309;
}
Cuándo usarlo
| Situación | Enfoque |
|---|---|
| Un elemento debe quedar encima de otro | Agregar position + z-index mayor al elemento que debe estar al frente |
| Un hijo no “gana” aunque tenga z-index alto | El padre crea un contexto — subir el z-index del padre, no del hijo |
| Pseudo-elemento decorativo detrás del contenido | z-index: -1 en el ::before/::after con position: absolute |
| Modal sobre toda la página | position: fixed; z-index: 300 (o valor de la escala de uso) |
| Aislar un grupo de elementos | isolation: isolate — crea contexto sin necesitar z-index |
Notas, gotchas e interacción
z-indexsinpositiones inerte. El error más frecuente: agregarz-index: 10a un elementostatic. El valor no produce efecto. La propiedad requiere quepositionsearelative,absolute,fixedosticky.opacity < 1crea un contexto de apilamiento. Cualquier elemento conopacitymenor que1— aunque no tengaz-index— crea un stacking context. Esto puede encerrar a los hijos e impedir que susz-indexcompitan con elementos externos. Veropacitypara el detalle de este efecto.transformyfiltertambién crean contexto. Un elemento contransform: translateY(0)(aunque sea inerte) crea un contexto de apilamiento. Es un patrón frecuente en animaciones y causa confusión cuando el z-index deja de “funcionar”.- No usar valores astronómicos.
z-index: 999999es un antipatrón. Cuando los z-index se escalan arbitrariamente, el sistema se vuelve inmanejable. Mejor usar una escala predefinida (10/100/300/1000) con variables CSS. isolation: isolatees la propiedad moderna para crear un contexto de apilamiento sin necesitarz-index. Útil cuando se quiere contener un componente sin afectar al layout de capas global:.componente { isolation: isolate; /* crea contexto; los z-index internos no compiten con el exterior */ }
Vigente / legacy
z-index es una propiedad CSS de larga data (CSS2) y no tiene forma legacy. Tiene soporte universal en todos los navegadores modernos sin prefijos. La propiedad isolation: isolate es la incorporación más reciente relacionada con el sistema de contextos — también tiene soporte amplio (Baseline widely).
Aprendelo en el recorrido
Esta propiedad se desarrolla en el módulo Positioning del recorrido. La lección positioning-02-fixed-sticky-z-index muestra el sistema de z-index con el modelo de contextos de apilamiento en un ejercicio con barra fija, títulos sticky y panel superpuesto.