Elegir entre CSS Grid y position absolute es una de las decisiones que más repito al maquetar: una etiqueta sobre una foto, un degradado sobre un hero, un menú que cae debajo de la barra. Las dos técnicas colocan un elemento encima de otro, pero por dentro no funcionan igual.
En este artículo comparo ambas con el mismo ejemplo, te enseño el bug que aparece cuando usas position: absolute de más y te dejo una regla para decidir en 5 segundos. Es mi opinión, y es un poco polémica.
En este tutorial
- Usa CSS Grid cuando varios elementos viven dentro del mismo contenedor y deben apilarse: etiquetas sobre una foto, overlays, héroes.
- Usa
position: absolutecuando el elemento debe salir del flujo: menús, tooltips, popovers o un indicador pegado al borde de otro elemento.
Qué vas a construir
No es un proyecto único, sino cuatro casos reales resueltos de las dos formas. Así ves en qué momento una técnica empieza a dar problemas y la otra no:
| Caso | Mejor opción | Por qué |
|---|---|---|
| Etiquetas sobre la foto de una tarjeta | CSS Grid | Cada etiqueta tiene su celda y no se pisan al estrechar la tarjeta |
| Hero con imagen, degradado y texto | CSS Grid | Los tres elementos comparten un área y order sustituye al z-index |
| Menú desplegable y popover de emojis | position: absolute | Deben salir del flujo y flotar sobre la página |
| Notificación sobre el borde de una foto | position: absolute | Sobresale de su contenedor: Grid no está pensado para eso |

El video, «¡DEJA de USAR Position en CSS! (en serio)», dura 12 minutos y va en este orden. Pulsa un capítulo para saltar a esa parte en YouTube:
- 0:00 Por qué creo que usas
positionde más - 0:56 La tarjeta de producto con
position: absolute - 2:59 El problema: las etiquetas se pisan
- 3:20 La solución con CSS Grid y
grid-template-areas - 6:32 Hero con overlay: imagen, degradado y texto
- 8:50 Cuándo sí usar
position: absolute: popover y menús - 10:03 La notificación en el borde de una foto
Qué necesitas
- Un editor de código, por ejemplo Visual Studio Code.
- Conocer lo básico de HTML y CSS: clases,
displayy márgenes. - Ayuda saber qué es
position: relative, pero lo repasamos en el primer paso.
Paso a paso
Una etiqueta sobre la foto con position absolute
El caso de siempre: una tarjeta con la etiqueta «Nuevo» encima de la imagen. Le das position: relative al contenedor para que sea la referencia y position: absolute a la etiqueta, con top y left para empujarla desde la esquina. Funciona, pero hay un coste: la etiqueta sale del flujo. El contenedor ya no la cuenta, no sabe qué hay a su lado y tú calculas las posiciones a ojo.
.card__media {
position: relative;
}
.badge {
position: absolute;
top: 12px;
left: 12px;
}
La misma etiqueta con CSS Grid
Con Grid y grid-template-areas conviertes el contenedor en una cuadrícula de una sola celda llamada stack. La imagen y la etiqueta se asignan a esa misma área, así que se apilan sin que ninguna salga del flujo. Después place-self coloca la etiqueta (centrada en vertical, al inicio en horizontal) y el margen sustituye al top y left de antes. El contenedor sigue creciendo con su contenido.
.card__media {
display: grid;
grid-template-areas: "stack";
}
.badge {
grid-area: stack;
place-self: center start;
margin: 12px;
}
Dos grupos de etiquetas sin que se pisen
Aquí es donde position: absolute falla. En la tarjeta de producto hay un grupo de etiquetas arriba a la izquierda («Más vendido», «Últimas unidades», «-15%») y otro arriba a la derecha («Oferta instantánea»). Con posición absoluta, si estrechas la tarjeta, un grupo se monta encima del otro porque ninguno sabe que el otro existe.
<ul class="card__badges">
<li class="badge badge--accent">Más vendido</li>
<li class="badge">Últimas unidades</li>
<li class="badge badge--danger">-15%</li>
</ul>
<ul class="card__badges card__badges--dos">
<li class="badge badge--accent">Oferta instantánea</li>
</ul>
Con Grid defines dos áreas, badges y badges-dos, y cada grupo ocupa la suya. La imagen abarca todas las columnas con grid-column: 1/-1. Si el espacio se acaba, las etiquetas saltan de línea en vez de superponerse. Prueba a arrastrar la esquina de la tarjeta: tiene resize: horizontal justo para eso.
.card{
resize: horizontal;
}
.card__media {
display: grid;
grid-template-areas: "badges badges-dos";
}
.card__media > img {
grid-column: 1/-1;
grid-row: 1/-1;
}
.card__badges{
grid-area: badges;
padding: 12px;
}
.card__badges--dos{
grid-area: badges-dos;
justify-self: end;
}
Un hero con overlay: imagen, degradado y texto en la misma celda
Un hero tiene tres capas: la imagen de fondo, un degradado que mejora la lectura y el texto. Es lo que muchos resuelven con tres position: absolute. Con Grid, la sección declara un área llamada overlay y los tres hijos se asignan a ella. El texto baja con align-self: end. Y como en el HTML va antes que la imagen y el degradado, estos lo taparían: order: 3 lo pinta el último, encima de los demás. Es el equivalente a un z-index, pero solo compara los elementos de ese contenedor.
.hero {
display: grid;
grid-template-areas: "overlay";
}
.hero__shade {
background: linear-gradient(to top, #0F0F14 10%, #0F0F14B3 45%, #0F0F1433);
}
.hero__bg,
.hero__shade, .hero__content{
grid-area: overlay;
}
.hero__content {
align-self: end;
order: 3;
}
Un popover que sí debe flotar: position absolute
Ahora al revés. Un botón «Reaccionar» abre una burbuja de emojis al pasar el ratón. Aquí sí quiero que la burbuja salga del flujo: no debe empujar nada ni ocupar espacio. El HTML usa el atributo popover, que enlaza el botón con la burbuja (popovertarget) y la muestra en la capa superior del navegador (*top layer*). El CSS le da position: absolute, y el ejemplo añade un poco de JavaScript para abrirla al pasar el ratón y calcular su top y left.
<button class="react" id="react" popovertarget="picker" aria-pressed="false">
...
</button>
<article class="picker" id="picker" popover>
...
</article>
.picker {
position: absolute; /* ★ top y left los calcula el JS (sin anchor) */
inset: auto;
margin: 0;
padding: 0 0 12px; /* puente invisible para el hover */
color: inherit;
background: none;
border: 0;
overflow: visible;
translate: -50% -100%;
}
Un menú desplegable que cae debajo de la barra
Otro clásico. La barra es la referencia (position: relative) y el panel se coloca con top: calc(100% + 8px): justo debajo de ella, con 8 píxeles de aire. Con Grid tendrías que reservar una fila vacía y empujar el contenido de la página, y un menú no debe empujar nada. Por eso aquí gana position: absolute.
.topbar {
position: relative;
}
.nav {
position: absolute;
top: calc(100% + 8px);
right: 0;
z-index: 5;
}
Una notificación pegada al borde de una foto
Último caso: un contador sobre el borde del círculo de una foto de perfil. El elemento sobresale de su contenedor, y las celdas de Grid no están pensadas para sobresalir. Con top, right y un translate de 50 %, la notificación queda justo en el borde a 45°. Podrías forzarlo con Grid, pero estarías reinventando la rueda.
.pet {
position: relative; /* ★ referencia para la notificación */
}
.pet__badge {
position: absolute;
top: 14.6%; /* ★ sobre el borde del círculo, a 45° */
right: 14.6%;
translate: 50% -50%;
}
Cuidado
position: absolute no se lleva bien con el diseño responsive: al sacar el elemento del flujo, el contenedor no reserva su espacio y cualquier cambio de ancho puede montar un elemento sobre otro. Si ves que tu diseño se rompe al estrechar la ventana, empieza por buscar qué elementos están en posición absoluta.
Consejo
Si no sabes cuál usar, hazte una pregunta: ¿este elemento debe ocupar sitio en su contenedor? Si la respuesta es sí (etiquetas, overlays, capas), usa Grid. Si debe flotar sin empujar a nadie (menús, tooltips, popovers), usa position: absolute.
Patrocinador oficial del curso
Publica tus proyectos con Hostinger
Hostinger es el patrocinador oficial del curso. Si quieres publicar estos ejemplos en internet con tu propio dominio, entra con el enlace de AlexCG Design y aprovecha el descuento.
Preguntas frecuentes
¿position: absolute está obsoleto?
No. Sigue siendo la herramienta correcta para menús desplegables, tooltips, popovers y elementos que sobresalen de su contenedor. Lo que conviene es dejar de usarlo para apilar elementos dentro de un mismo contenedor, donde Grid evita los solapamientos y mantiene el diseño dentro del flujo.
¿Puedo superponer dos elementos con CSS Grid?
Sí. Asigna el mismo área (grid-area) a los dos elementos y se colocarán en la misma celda, uno encima del otro. Con align-self, justify-self o place-self decides dónde queda cada uno dentro de esa celda, y con order cuál se pinta encima.
¿Qué es mejor para el responsive, Grid o position absolute?
Grid, en la mayoría de los casos. Los elementos en Grid siguen en el flujo, así que el contenedor se adapta a su tamaño y las etiquetas saltan de línea en vez de pisarse. Con position: absolute, tú calculas cada posición y cualquier cambio de ancho puede romper el diseño.
¿Sirve order en Grid para sustituir a z-index?
Cuando varios elementos comparten la misma celda, sí: el de mayor order se pinta encima del resto. Es más sencillo que el z-index porque solo compara los elementos de ese contenedor. Para capas que viven fuera de él, como un menú o un popover, sigues necesitando z-index.
Más proyectos
- Cómo crear un dropdown menú con CSS
- 3 características que no conocías de CSS
- Cómo crear una página web con HTML, CSS y JavaScript
Curso
Domina CSS desde cero
Estoy preparando un curso de CSS donde Grid, Flexbox y position se explican con proyectos reales.



