CSS: z-index no funciona — Por qué y cómo solucionarlo
Explica por qué el z-index no funciona en CSS y cómo solucionar problemas de apilamiento de elementos. Stacking context, position y overflow explicados.
¿Por qué ocurre?
El z-index no funciona porque: - El elemento no tiene `position` distinto de `static` (el valor por defecto) - Un elemento padre crea un nuevo stacking context que limita el z-index de sus hijos - `transform`, `opacity < 1`, `filter`, `will-change`, `isolation` o `contain` en el padre crean un nuevo stacking context automáticamente - Los z-index se comparan entre hermanos dentro del mismo contexto de apilamiento, no de forma global
Solución paso a paso
1. Añadir position al elemento
/* ❌ z-index ignorado con position: static (valor por defecto) */
.mi-elemento {
z-index: 999;
}/* ✅ z-index funciona con cualquier position distinto de static */
.mi-elemento {
position: relative; /* o absolute, fixed, sticky */
z-index: 999;
}
2. Identificar el stacking context del padre
/* ❌ El padre tiene transform — crea nuevo stacking context */
/* El hijo nunca podrá superar al elemento externo */
.padre {
transform: translateX(0); /* ← Crea stacking context */
}
.hijo {
position: absolute;
z-index: 9999; /* Inútil fuera del contexto del padre */
}/* ✅ Solución: mover el elemento fuera del padre problemático */
/* O usar isolation: isolate conscientemente */
3. Usar isolation para crear stacking context intencionado
/* Crear un contexto de apilamiento limpio */
.modal-container {
isolation: isolate;
position: relative;
z-index: 100;
}
4. Sistema de z-index con variables CSS
:root {
--z-below: -1;
--z-base: 0;
--z-dropdown: 100;
--z-sticky: 200;
--z-overlay: 300;
--z-modal: 400;
--z-popover: 500;
--z-toast: 600;
--z-tooltip: 700;
}.header {
position: sticky;
top: 0;
z-index: var(--z-sticky);
}
.modal {
position: fixed;
inset: 0;
z-index: var(--z-modal);
}
5. Caso Tailwind: z-index y stacking context
No puede salir del padre
6. Debuggear el stacking context
// En DevTools Console: ver qué crea stacking context
// Busca elementos con: transform, opacity < 1, filter, will-change,
// position + z-index, isolation: isolate, contain: layout/paint/strict
document.querySelectorAll('*').forEach(el => {
const style = getComputedStyle(el);
const creates = style.transform !== 'none' ||
parseFloat(style.opacity) < 1 ||
style.filter !== 'none' ||
style.isolation === 'isolate';
if (creates) console.log('Stacking context:', el);
});
Cómo evitarlo en el futuro
- Define un sistema de z-index con variables CSS desde el inicio del proyecto - Evita usar números mágicos como `z-index: 9999` - Ten cuidado con `transform`, `opacity`, `filter` en elementos padres de elementos posicionados - Usa las DevTools → Layers panel para visualizar el árbol de stacking contexts
¿Quieres que una IA te ayude? Genera el prompt perfecto para tu error:
Generador de Prompts