Posicionamiento y z-index en CSS
En esta lección
Normalmente los elementos se colocan solos, uno detrás de otro, siguiendo el flujo normal del documento. La propiedad position permite sacarlos de ese flujo o desplazarlos. Es la herramienta para cosas como insignias sobre una tarjeta, menús que se quedan fijos arriba o ventanas emergentes.
Para maquetar la página en columnas no se usa position: para eso están Flexbox y Grid.
static (por defecto)
El elemento sigue el flujo normal. Las propiedades top, right, bottom y left no le afectan.
relative
El elemento se queda en su sitio en el flujo (su hueco se respeta), pero puedes desplazarlo respecto a donde estaría:
.icono { position: relative; top: 2px; } /* baja 2px, sin mover nada más */
Su uso principal, sin embargo, es otro: servir de referencia para los hijos con position: absolute.
absolute
El elemento sale del flujo: los demás se comportan como si no existiera. Se coloca con top, right, bottom y left respecto a su ancestro posicionado más cercano (el primer padre, abuelo… que tenga un position distinto de static). Si no hay ninguno, se coloca respecto a la página.
El patrón más habitual:
.tarjeta { position: relative; } /* la referencia */
.tarjeta .insignia {
position: absolute;
top: 8px;
right: 8px; /* esquina superior derecha de la tarjeta */
}
Si tu elemento absoluto aparece en una esquina de la página en vez de donde esperabas, casi siempre es porque olvidaste el position: relative en el padre.
Truco para que un elemento absoluto ocupe todo su padre:
.capa { position: absolute; inset: 0; } /* inset: 0 = top, right, bottom y left a 0 */
fixed
Como absolute, pero respecto a la ventana del navegador: se queda en el mismo sitio aunque hagas scroll.
.boton-whatsapp {
position: fixed;
bottom: 20px;
right: 20px;
}
Se usa para botones flotantes, avisos de cookies o barras que siempre están visibles. No abuses: en un móvil, cada elemento fijo le quita pantalla al contenido.
sticky
Una mezcla: el elemento se comporta como relative hasta que, al hacer scroll, llega a la posición indicada, y a partir de ahí se queda pegado como si fuera fixed, pero solo dentro de su contenedor.
.cabecera { position: sticky; top: 0; }
thead th { position: sticky; top: 0; background: white; }
Perfecto para cabeceras de página, cabeceras de tablas largas o índices laterales. Necesita que le digas en qué punto pegarse (top: 0, por ejemplo) y no funciona si algún ancestro tiene overflow: hidden.
Superposición: z-index
Cuando varios elementos posicionados se solapan, z-index decide cuál queda encima. Un número mayor queda más arriba:
.menu-desplegable { position: absolute; z-index: 10; }
.modal-fondo { position: fixed; z-index: 100; }
.modal { position: fixed; z-index: 101; }
- Solo funciona en elementos con
positiondistinto destatic(o hijos de Flexbox o Grid). - Si no pones
z-index, el que aparece más tarde en el HTML queda encima.
El problema de los contextos de apilamiento
A veces pones z-index: 9999 y el elemento sigue debajo. Es porque los z-index solo se comparan entre hermanos del mismo “contexto”: si el padre tiene z-index: 1 y otro elemento de fuera tiene z-index: 2, todos los hijos del primero quedarán debajo, aunque tengan z-index: 9999. Crean un contexto nuevo, entre otras cosas, un position con z-index, un opacity menor que 1 o un transform.
La solución suele ser subir el z-index al contenedor, no al hijo. Y usar una escala ordenada (1, 10, 100…) en vez de números al azar.
Centrar un elemento posicionado
.centrado {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
top y left al 50 % colocan la esquina del elemento en el centro; el translate lo desplaza la mitad de su propio tamaño para centrarlo de verdad. (Si puedes, es más sencillo centrar con Flexbox o Grid en el padre.)
Resumen
| Valor | ¿Ocupa su hueco? | Se coloca respecto a… | Uso típico |
|---|---|---|---|
static | Sí | (no se mueve) | Por defecto |
relative | Sí | Su posición normal | Referencia para hijos absolutos |
absolute | No | El ancestro posicionado más cercano | Insignias, iconos sobre imágenes, desplegables |
fixed | No | La ventana | Botones flotantes, avisos |
sticky | Sí | Su contenedor, al hacer scroll | Cabeceras que se quedan pegadas |
Pruébalo tú
Cambia el código y pulsa Ejecutar (o Ctrl + Enter).
Pon a prueba lo que has aprendido
¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.