wandres.dev
ALINEACIÓN UNIFICADA · La caja de alineación en todo

Qué eje es cuál: justify y align en flex, grid y bloque

En Grid justify es siempre el eje en línea; en Flexbox depende de flex-direction. Ese detalle explica el 90% de las alineaciones que parecen no funcionar.

⏱ 16 min

La confusión más cara del módulo de alineación no está en los valores, está en el eje. justify-content: center centra horizontalmente en una rejilla y en un flex de fila, pero centra verticalmente en un flex de columna, y esa asimetría no es un capricho: es la consecuencia directa de que Flexbox razone en ejes relativos a su dirección mientras Grid razona en ejes relativos al modo de escritura. Una vez lo entiendes, dejas de probar propiedades al azar.

🎯 Al terminar esta lección sabrás
  • Enunciar la regla de ejes de Grid y la de Flexbox y explicar por qué son distintas.
  • Predecir el efecto de justify-content en un flex de columna sin probarlo.
  • Razonar la alineación en un documento con writing-mode vertical.
  • Diagnosticar en dos pasos una alineación que “no funciona”.

La regla de Grid: ejes fijos al modo de escritura

En Grid la correspondencia es constante y no depende de nada del contenedor:

  • justify-* actúa sobre el eje en línea: el eje en el que fluye el texto.
  • align-* actúa sobre el eje de bloque: el eje en el que se apilan los párrafos.

En un documento occidental normal, eje en línea es horizontal y eje de bloque es vertical. Por eso justify-items: center centra horizontalmente y align-items: center centra verticalmente, siempre, sin excepciones y sin importar cómo estén definidas las pistas.

La regla mnemotécnica que sí resiste: justify comparte raíz con justificar un texto, que es una operación en la dirección de la línea. Si te acuerdas de eso, no vuelves a dudar en Grid.

La regla de Flexbox: ejes relativos a la dirección

Flexbox no habla de eje en línea y eje de bloque: habla de eje principal y eje transversal, y el principal lo elige flex-direction.

  • justify-content actúa sobre el eje principal.
  • align-items, align-self y align-content actúan sobre el eje transversal.
.fila {
  display: flex;                /* eje principal = horizontal */
  justify-content: center;      /* centra en horizontal */
  align-items: center;          /* centra en vertical */
}

.columna {
  display: flex;
  flex-direction: column;       /* eje principal = vertical */
  justify-content: center;      /* ahora centra en VERTICAL */
  align-items: center;          /* ahora centra en HORIZONTAL */
}

Las dos reglas son igual de razonables desde su propio punto de vista. Flexbox se diseñó como un layout de una dimensión donde lo que importa es “a lo largo” y “a lo ancho”, conceptos que solo tienen sentido relativos a la dirección elegida. Grid se diseñó como un layout de dos dimensiones simétricas, donde no hay una dirección privilegiada y hay que anclar los nombres a algo externo: el modo de escritura.

⚠️
El caso que rompe la intuición de todo el mundo

Una columna de flex donde quieres que los hijos se estiren a lo ancho no necesita justify-content: stretch —que además no es un valor con efecto ahí—: necesita align-items: stretch, que ya es el valor por defecto. Y si los hijos no se estiran a pesar de eso, casi siempre es porque tienen width o align-self puestos, o porque son elementos de reemplazo con proporción propia.

Modos de escritura: donde Grid demuestra que tenía razón

Cambia el modo de escritura y verás por qué la especificación eligió ejes lógicos.

.vertical {
  writing-mode: vertical-rl;   /* el texto fluye de arriba abajo */
  display: grid;
  grid-template-columns: repeat(2, 1fr);  /* "columnas" ahora son horizontales */
  justify-items: start;        /* start = arriba, porque el eje en linea es vertical */
  align-items: center;         /* centra en el eje de bloque, ahora horizontal */
}

Nada de esto hay que reescribirlo al traducir un sitio a japonés vertical o a un idioma de derecha a izquierda: las propiedades siguen significando lo mismo y el navegador reinterpreta la geometría. Ese es el motivo por el que conviene abandonar flex-start y flex-end en favor de start y end, y width/height en favor de inline-size/block-size, aunque hoy solo publiques en español.

En Flexbox el modo de escritura también cuenta, pero en segundo plano: flex-direction: row significa “a lo largo del eje en línea”, así que en vertical-rl una fila de flex se dibuja verticalmente. La cadena es la misma, solo que con un nivel de indirección más.

El diagnóstico en dos pasos

Cuando una alineación no hace nada, no pruebes valores. Hazte dos preguntas en este orden.

Primera: ¿estoy en el eje que creo? Comprueba el display del contenedor y, si es flex, su flex-direction. La mitad de los casos se resuelven aquí: estabas escribiendo align-items cuando el eje que querías tocar era el principal.

Segunda: ¿hay espacio sobrante en ese eje? Una distribución solo puede repartir lo que sobra. En un contenedor de altura automática nunca sobra altura, porque la altura es exactamente la del contenido. Es la razón número uno de que align-items: center “no funcione” en un flex de fila: el contenedor mide lo que mide el hijo más alto, así que todos ya están centrados respecto a un espacio de cero.

/* no hace nada: la altura del contenedor la fija el contenido */
.sin-altura { display: flex; align-items: center; }

/* si hace algo: ahora hay altura sobrante que repartir */
.con-altura { display: flex; align-items: center; block-size: 12rem; }

Las herramientas de desarrollo ayudan mucho aquí: los superpuestos de flex y grid dibujan los ejes y las zonas de espacio libre, con lo que las dos preguntas se responden mirando en vez de deduciendo.

Los dos sistemas de ejes son una fractura histórica, no un diseño coherente

Merece la pena saber de dónde viene esta incomodidad, porque explica por qué no va a desaparecer. Flexbox se especificó antes de que existiera el módulo de Box Alignment, con su propio vocabulario cerrado —flex-start, flex-end, eje principal, eje transversal— pensado para un mundo de una sola dimensión. Cuando llegó Grid y se decidió que la alineación debía ser un módulo común, hubo que reconciliar ese vocabulario con uno nuevo basado en ejes lógicos, y la reconciliación se hizo sin romper la web existente: los valores viejos siguen ahí con su semántica vieja, los nuevos se añadieron encima, y las dos capas conviven. Lo que estás aprendiendo cuando memorizas que justify cambia de eje en Flexbox no es una regla de diseño: es un fósil de compatibilidad hacia atrás, exactamente igual que el modo quirks o que el hecho de que line-height sin unidad se herede de forma distinta que con unidad. La habilidad de verdad no es memorizar la excepción, es reconocer cuándo una rareza es una decisión y cuándo es una cicatriz; las decisiones tienen una lógica que puedes extrapolar a casos nuevos, las cicatrices solo se pueden recordar, y confundir unas con otras te lleva a inventar reglas generales que no existen.