z-index no funciona: 5 soluciones definitivas
“Le puse z-index: 9999 y sigue detrás” 😤 Si esto te suena familiar, este artículo es para ti.
El problema de z-index no suele ser el valor que asignas, sino el contexto de apilamiento que estás ignorando.
La causa raíz: stacking context
Cada elemento HTML crea su propio contexto de apilamiento. Los elementos hijos solo pueden estar dentro de ese contexto, nunca salir de él.
Esto significa:
- Aunque tu hijo tenga
z-index: 9999 - Si su padre tiene
z-index: 1 - El hijo nunca podrá estar encima de elementos externos al padre
Las 5 soluciones
Solución 1: Añade position al elemento
z-index solo funciona con elementos posicionados.
/* ❌ NO funciona */
.boton-flotante {
z-index: 100;
}
/* ✅ CORRECTO */
.boton-flotante {
position: relative;
z-index: 100;
}
Valores válidos de position: relative, absolute, fixed, sticky
Solución 2: Saca al hijo del contexto del padre
Si el padre está limitando a tu hijo, tienes opciones:
Opción A: Mueve el HTML
<!-- ❌ El dropdown está dentro de .header -->
<div class="header">
<div class="dropdown">...</div>
</div>
<!-- ✅ El dropdown está fuera -->
<div class="header"></div>
<div class="dropdown">...</div>
Opción B: Usa Portal (React/Vue)
// React - Renderiza fuera del padre
import { createPortal } from 'react-dom';
return createPortal(
<Dropdown />,
document.body
);
Solución 3: Remueve propiedades que crean nuevo contexto
Estas propiedades crean stacking context automáticamente:
opacitymenor a 1transform(cualquier valor exceptonone)filterisolation: isolateposition: fixed
/* ❌ Crea nuevo contexto */
.caja {
opacity: 0.9;
transform: scale(1.1);
}
/* ✅ Alternativas sin crear contexto */
.caja {
background: rgba(255, 255, 255, 0.9);
/* transform eliminado */
}
Solución 4: Usa position: fixed para overlays
Para modales y popups, position: fixed es más confiable:
.modal-overlay {
position: fixed;
z-index: 9999;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
}
.modal-contenido {
position: relative;
z-index: 10000; /* Mayor que el overlay */
}
Solución 5: Establece el z-index del padre
A veces, solo necesitas darle al padre el z-index correcto:
.header {
position: relative;
z-index: 100;
}
.dropdown {
position: absolute;
z-index: 200; /* Ahora funciona */
top: 100%;
}
Ejemplo completo: Modal que no aparece
El problema
<div class="modal-container"> <!-- z-index: 1 -->
<div class="modal"> <!-- z-index: 9999 - NO FUNCIONA -->
Contenido
</div>
</div>
La solución
<div class="modal-container">
<!-- El modal se rendered en document.body via portal -->
</div>
<!-- O directamente: -->
<div class="modal">
Contenido
</div>
.modal {
position: fixed; /* Crea contexto independiente */
z-index: 9999;
/* Centrado */
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Tabla de referencias rápidas
| Problema | Solución |
|---|---|
| z-index no tiene efecto | Añadir position: relative/absolute/fixed/sticky |
| Hijo detrás de elementos externos | Remover el padre del flujo o usar portal |
| z-index no supera a otros | Verificar z-index del padre |
| Elementos se cortan | Revisar overflow: hidden del padre |
| Modal detrás de header | Usar position: fixed en el modal |
Artículos relacionados
- Problemas z-index CSS: Guía completa
- Entiende el contexto de apilamiento CSS
- z-index modal no funciona
- Dropdown menú z-index problemas
- z-index con overflow:hidden
- CSS Position explicados
: El número en z-index no es la respuesta. El contexto lo es.