El posicionamiento en CSS mediante la propiedad position es el mecanismo que nos permite sacar a elementos de su flujo natural y colocarlos en otro punto de la pantalla.
Hasta ahora, el navegador apilaba nuestras cajas una debajo de la otra de forma predecible y ordenada, ocupando todo el ancho disponible.
Pero a veces necesitamos romper esas reglas para crear diseños más complejos, como superponer un texto sobre una imagen, dejar un menú superior anclado o poner un botón flotante en una esquina.
En CSS, la propiedad position nos otorga esa capacidad de control sobre la ubicación de cada elemento en nuestra página. Para moverlos, usaremos unas coordenadas especiales: top, bottom, left y right.
Pero antes de empezar a mover cosas, hay unas cuantas cosas que debemos saber sobre los distintos modos de posicionamiento que tenemos a nuestra disposición.
Flujo normal (position: static)
Por defecto, absolutamente todas las etiquetas HTML tienen con un posicionamiento static. Es el más sencillo y básico.
Esto simplemente significa que el navegador las coloca en el orden en el que aparecen en vuestro código HTML.
Un elemento estático ignora por completo cualquier coordenada de desplazamiento (top, bottom, etc.) que intentéis aplicarle. Simplemente se deja llevar por la corriente de la página.
Relativo (position: relative)
Si le aplicamos position: relative a una caja, a simple vista no pasará absolutamente nada. El comportamiento será igual al de static.
Sin embargo, relative activa sus coordenadas de movimiento. Es decir, que podemos usar las propiedades de dirección para desplazar la caja tomando como referencia su posición original.
.caja-movida {
position: relative;
top: 20px; /* La empuja 20px hacia ABAJO desde su posición original */
left: 10px; /* La empuja 10px hacia la DERECHA desde su posición original */
}
Con el posicionamiento relative es que el elemento se mueve visualmente por la pantalla, pero su espacio geométrico original sigue reservado e intacto en el flujo del documento.
Las cajas adyacentes no se reajustarán ni colapsarán para ocupar su hueco; actuarán como si la caja siguiera en su sitio original.
Esto provoca que el elemento movido se superponga visualmente a otras partes de la interfaz (lo cual suele ser exactamente el efecto deseado).
Posición absoluta (position: absolute)
Al aplicar :key[position: absolute], le estamos ordenando al navegador que elimine y arranque por completo el elemento del flujo normal del documento.
A nivel estructural, la caja dejará de existir para sus elementos hermanos. Su espacio original colapsará instantáneamente y el resto de la página se reordenará hacia arriba, como si ese elemento HTML jamás hubiera sido escrito en el editor de código.
Una vez arrancada, la caja buscará un punto de referencia para inyectar sus coordenadas top, bottom, left o right de forma relativa a su Positioning Context.
.contenedor-padre {
position: relative; /* Crea la jaula o contexto de posicionamiento */
width: 300px;
height: 300px;
}
.hijo-absoluto {
position: absolute;
bottom: 0; /* Se pega al suelo interior de su contenedor padre */
right: 0; /* Se pega a la pared derecha interior de su contenedor padre */
}
¿Qué significa Positioning Context?
La mayoría de la gente le tiene pánico al posicionamiento absoluto, porque les ha salido “una caja volando”. El motivo es que hay que entender el positioning context.
Los elementos con position: absolute se posicionan respecto al primer elemento padre que no sea static.
Si el padre es static (el valor por defecto), lo ignorará y mirará al abuelo. Si el abuelo también es static, seguirá subiendo hasta llegar a la etiqueta raíz <html>.
En resumen, que si no quieres que tu elemento absolute salga volando, tienes que ponerle a un elemento padre relative (generalmente, u otro que no sea static).
Anclado a la pantalla (position: fixed)
El posicionamiento :key[fixed] se clava en un punto de la pantalla, sin importarle nada más. En un hermano mayor, más radical, del posicionamiento absoluto.
Al igual que el absolute, arranca al elemento del flujo del documento por completo y no deja rastro de su espacio.
Pero fixed ignora totalmente a todos sus padres y contenedores en el DOM. Su único y exclusivo punto de referencia es el Viewport (la ventana física y visible del navegador en vuestra pantalla).
Si le decís a un elemento fixed que se coloque en top: 0 y left: 0, se clavará en la esquina superior izquierda de vuestro monitor. Y no se moverá de ahí bajo ningún concepto técnico, por mucho que el usuario haga scroll vertical u horizontal a través de una página kilométrica.
Es la herramienta estándar para crear menús de navegación superiores que te persiguen mientras lees un artículo, o posicionar elementos fijos en aplicaciones web.
Pegajoso (position: sticky)
Llegamos a la última incorporación al estándar CSS. Sirve, por ejemplo, para crear elementos que se desplazan con el scroll, pero luego se quedan en la parte superior “pegadas”.
Un elemento con :key[position: sticky] actúa como una mezcla dinámica entre relative y fixed. Al cargar la web, la caja se comporta como relative, ocupando el flujo del documento.
Pero, cuando el usuario hace scroll, cuando la caja cruza un umbral (threshold) que le hayamos definido por coordenadas, se queda “pegada” flotando en la pantalla.
.titular-seccion {
position: sticky;
top: 0px; /* Compórtate normal hasta que toques el techo (0px) de la pantalla, entonces pégate */
background-color: darkblue;
color: white;
}
Es muy común quejarse de que sticky no funciona. Para que el motor lo active, se deben cumplir dos condiciones estrictas:
- Debéis declarar obligatoriamente al menos una coordenada de activación (
top,bottom,leftoright). Sin ella, el elemento seguirá siendo estático para siempre. - Ninguno de los contenedores padres o abuelos en el DOM puede tener declarada la propiedad
overflow: hidden,overflow: scrollooverflow: auto. Si la tienen, el contexto de scroll se interrumpe y el efecto pegajoso se rompe instantáneamente.
Controlando el eje Z (z-index)
En el momento exacto en el que empezamos a arrancar cajas de su flujo con absolute o fixed, es inevitable que se solapen unas encima de otras, tapando el texto o las imágenes.
Por defecto, el navegador renderiza las capas usando el orden del código HTML: la etiqueta que esté escrita más abajo en vuestro archivo se dibujará por encima del resto.
Para alterar esta regla y tomar el control del eje de profundidad (la tercera dimensión hacia los ojos del usuario), usamos la propiedad z-index.
Esta propiedad admite valores numéricos enteros, tanto positivos como negativos. Una caja con z-index: 10 siempre se dibujará por encima y ocultará visualmente a una caja con z-index: 1.
La propiedad z-index SOLO se activa sobre elementos que hayan sido posicionados.
Si le aplicáis z-index: 9999 a un elemento que sigue teniendo el position: static por defecto, el motor de renderizado os ignorará olímpicamente y la capa no se moverá ni un milímetro hacia el frente.
