
En resumen
Para un solo elemento, Grid con place-items: center es la respuesta más corta y correcta. Flexbox lo es cuando el padre tiene varios hijos, y margin: auto salva el caso en que el contenido desborda.
Cómo centrar un div en CSS depende del padre, y por eso "centrar un div" se convirtió en un chiste y CSS acabó teniendo tres formas buenas de hacerlo. Esta guía da primero la respuesta corta, después el método para cada situación y por último las trampas que explican por qué una técnica que funciona en una maquetación falla en silencio en la siguiente.
Cada ejemplo se puede pegar en el playground de CSS de UrsaKit para ver la maquetación actualizada.
01Las respuestas cortas
/* Un elemento, ambos ejes, el padre tiene altura */
.parent {
display: grid;
place-items: center;
}
/* Varios hijos, uno o ambos ejes */
.parent {
display: flex;
justify-content: center;
align-items: center;
}
/* Un bloque con ancho, solo horizontal */
.child {
width: min(100%, 40rem);
margin-inline: auto;
}
Esos tres casos cubren la gran mayoría. El resto del artículo explica de qué depende cada uno.
02Flexbox: la respuesta por defecto
Flexbox reparte el espacio libre a lo largo de un eje y alinea los ítems en el otro.
.parent {
display: flex;
justify-content: center; /* eje principal: horizontal por defecto */
align-items: center; /* eje cruzado: vertical por defecto */
min-height: 100vh;
}
Dos detalles deciden si funciona:
- El eje principal sigue a
flex-direction. Conflex-direction: column,justify-contentcontrola el eje vertical yalign-itemsel horizontal. Leer esas propiedades como "horizontal" y "vertical" es lo que hace que el centrado parezca roto. - El contenedor necesita espacio libre.
align-items: centerreparte la altura que sobra después de los hijos. Si la altura del padre es igual a su contenido, no hay nada que repartir y el elemento se queda donde estaba.
Usa
place-content: centerpara centrar todo el grupo.
justify-contentyalign-contentcolocan las líneas de un contenedor flex o grid. Si varios hijos deben quedarse juntos como grupo centrado en lugar de repartirse, ponplace-content: centery dejaalign-itemscon su valor por defecto.
03Grid: dos líneas para los dos ejes
Grid puede centrar un hijo en ambos ejes sin que el padre sepa nada del tamaño del hijo.
.parent {
display: grid;
place-items: center;
min-height: 100vh;
}
place-items: center es la abreviatura de align-items: center y justify-items: center, y funciona porque el hijo ocupa su propia área de grid en lugar de una línea flex compartida.
La abreviatura está pensada para Grid. En Flexbox justify-items no se aplica, porque los ítems del eje principal se tratan como un grupo, así que el segundo valor de place-items se ignora.
La diferencia práctica con Flexbox aparece con varios hijos:
| Maquetación | Flexbox | Grid |
|---|---|---|
| Un hijo centrado | Funciona | Lo más corto |
| Hijos en fila, centrados como grupo | justify-content: center | place-content: center |
| Cada hijo centrado en su celda | Incómodo | place-items: center |
| Columnas de igual altura | Requiere cuidado con align-items: stretch | Nativo |
04margin: auto
Para un elemento de bloque con un ancho menor que su contenedor, los márgenes auto reparten el espacio sobrante:
.child {
width: min(100%, 40rem);
margin-inline: auto;
}
Lo que sorprende es la versión vertical. En maquetación de bloque normal, los márgenes verticales auto se calculan como cero, así que margin: auto no centra un bloque en vertical:
/* NO centra en vertical: el padre no es flex ni grid */
.parent {
height: 100vh;
}
.child {
margin: auto;
}
/* SÍ centra en vertical: el hijo ahora es un ítem flex */
.parent {
display: flex;
height: 100vh;
}
.child {
margin: auto;
}
Esto es más que una curiosidad: margin: auto en el ítem es la solución estándar al problema de desbordamiento de más abajo.
05Posicionamiento absoluto cuando no controlas el padre
Si el padre debe seguir siendo un bloque normal —un contenedor de canvas, una presentación, marcado renderizado por una biblioteca— saca el elemento del flujo:
.parent {
position: relative;
}
.overlay {
position: absolute;
inset: 0;
margin: auto;
width: 200px;
height: 100px;
}
inset: 0 con margin: auto centra una caja de tamaño fijo sin conocer las dimensiones del padre. Cuando el tamaño es desconocido, la alternativa es la versión con transform:
.overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
El enfoque con transform saca el elemento de la maquetación del padre, así que úsalo como respaldo y no por defecto.
06Texto y contenido en línea
El contenido en línea lo centra el text-align de su padre, y el centrado vertical es otro problema:
.title {
text-align: center;
}
.badge {
display: grid;
place-items: center;
min-height: 2.5rem;
}
/* Truco heredado de una línea: solo sirve para una línea */
.button {
line-height: 2.5rem;
height: 2.5rem;
}
El centrado con line-height se rompe en cuanto el texto pasa a dos líneas, porque la caja de línea mantiene la altura de una mientras el contenido crece. Prefiere flex o grid en el propio elemento.
07Las trampas que rompen cada método
| Método | Falla cuando | Solución |
|---|---|---|
| Flexbox, ambos ejes | El contenedor no tiene altura extra | Añade min-height o da altura al padre |
| Flexbox, ambos ejes | El hijo centrado es mayor que el contenedor | Usa margin: auto en el ítem, o justify-content: safe center |
justify-content con flex-direction: column | Las expectativas de eje se invierten | Cambia a align-items para el eje horizontal |
margin: auto | El padre es maquetación de bloque normal | Convierte el padre en flex o grid |
margin-inline: auto | El elemento tiene width: 100% | Define un ancho máximo, por ejemplo max-width: 40rem |
| Absoluto + transform | El padre no está posicionado | Pon position: relative en el padre |
Centrado con line-height | El texto se parte en dos líneas | Usa grid o flex |
Un ítem flex centrado puede esconder su propio borde superior.
Si el contenido es más alto que el contenedor y se aplica
justify-content: center(oalign-items: center), el desbordamiento se extiende por encima del origen de scroll y las primeras líneas dejan de ser alcanzables. Añadirmargin: autoal ítem, o usarsafe center, mantiene el inicio del contenido desplazable.
08Depurar un problema de centrado
- Mira primero la altura del padre — En el panel de maquetación de las herramientas de desarrollo, selecciona el padre. Si su altura coincide con la de su contenido, el centrado vertical no tiene con qué trabajar.
- Comprueba qué eje usa el padre —
flex-direction: rowsignifica quejustify-contentes horizontal. Cambiar a column sin tocar las propiedades es la causa más habitual de "dejó de centrarse". - Busca un ancho del 100% — Un elemento que ya llena su contenedor no deja espacio libre, así que los márgenes auto no hacen nada.
- Prueba con contenido real, no con el estado vacío — Centra con texto realista y luego con texto que desborde, usando el playground de CSS. Casi todos los errores de centrado solo aparecen cuando el contenido crece.
Acertar con esto consiste, sobre todo, en saber qué elemento posee el espacio libre. Cuando eso queda claro, los nombres de las propiedades dejan de ser misteriosos.
09Fuentes
- MDN — Aligning items in a flex container: espacio libre y los ejes principal y cruzado (fecha de consulta: 2026-10-09)
- MDN — justify-content: reparto en el eje principal y la palabra clave safe (fecha de consulta: 2026-10-09)
- MDN — align-items: alineación en el eje cruzado (fecha de consulta: 2026-10-09)
- MDN — place-items: la abreviatura y por qué Flexbox ignora justify-items (fecha de consulta: 2026-10-09)
- MDN — margin: márgenes auto y centrado (fecha de consulta: 2026-10-09)
- W3C — CSS 2.1, modelo de formato visual: los márgenes auto valen cero en el eje de bloque (fecha de consulta: 2026-10-09)
- MDN — inset: posicionar una caja de tamaño fijo con márgenes auto (fecha de consulta: 2026-10-09)
- MDN — line-height: altura de la caja de línea y saltos de línea (fecha de consulta: 2026-10-09)
- MDN — text-align: alineación del contenido en línea (fecha de consulta: 2026-10-09)
- W3C — CSS Box Alignment Module Level 3: alineación de desbordamiento safe y unsafe (fecha de consulta: 2026-10-09)
- W3C — CSS Transforms Module Level 1: transform y maquetación (fecha de consulta: 2026-10-09)
Edita CSS contra marcado real y mira cómo cambia la maquetación mientras escribes.
Playground de CSSPreguntas frecuentes
¿Cuál es la forma más corta de centrar un elemento en ambos ejes?
Convierte el padre en contenedor grid y añade place-items: center. El elemento queda centrado en horizontal y vertical y el padre no necesita conocer su tamaño.
¿Por qué align-items: center no hace nada?
Porque el padre no tiene altura sobrante que repartir. El centrado vertical necesita una altura definida, un min-height o una línea flex/grid estirada.
¿Por qué margin: auto solo centra en horizontal?
En maquetación de bloque normal, los márgenes auto reparten el espacio inline sobrante. Para centrar en vertical con márgenes auto el elemento debe ser un ítem flex o grid, donde el eje de bloque también reparte espacio libre.
¿Por qué no puedo desplazarme hasta arriba de un elemento centrado con flex?
Cuando un ítem flex es más grande que su contenedor y se aplica justify-content: center, el desbordamiento queda por encima del origen de scroll. Usa margin: auto en el ítem o safe center.
¿place-items solo funciona en Grid?
place-items es la abreviatura de align-items y justify-items, que funcionan en Grid y parcialmente en Flexbox. En Flexbox justify-items no tiene efecto porque los ítems los reparte justify-content.
¿Sigo necesitando posición absoluta con transform?
Solo cuando el padre no puede convertirse en flex o grid, por ejemplo si lo controla una biblioteca o el elemento debe colocarse sobre un canvas.
Artículos relacionados
- La estructura de un documento HTML, explicada
Comprueba que el marcado que centras es el que crees.
- Comprime imágenes sin perder calidad visible
Por qué width y height en el elemento siguen importando.
Herramientas relacionadas
- Playground de CSS
Prueba cada método de centrado con marcado real.
- Herramienta HTML Online
Construye el marcado al que apunta el CSS.
- Ejecutor de JavaScript
Mide el resultado de un cambio de maquetación.
- Comparador de texto
Compara dos hojas de estilo antes y después.