Accede a todo EDteam con un único pago¡Sube a premium!

Guia definitva de flexbox (1) - Main axis y cross axis

Flexbox es el chico nuevo en CSS, de ser un tema conversado con cierto misticismo en los foros empieza a convertirse en un tema imprescindible para quienes desarrollamos aplicaciones y páginas web. Hoy muchos saben que poniendo display:flex suceden cosas mágicas. Sin embargo, necesitamos comprender a fondo la teoría para sacarle el mayor provecho.

Diseño web
9 minutos
Hace 7 años
Guia definitva de flexbox (1) - Main axis y cross axis

Flexbox es el chico nuevo en CSS, de ser un tema conversado con cierto misticismo en los foros empieza a convertirse en un tema imprescindible para quienes desarrollamos aplicaciones y páginas web. Hoy muchos saben que poniendo display:flex suceden cosas mágicas. Sin embargo, necesitamos comprender a fondo la teoría para sacarle el mayor provecho.

Y es que Flexbox no se puede simplificar a una lista de propiedades y valores, sino que se requiere un conocimiento profundo de qué está pasando internamente con los elementos (por ejemplo, ¿Qué sucede con los márgenes, paddings, altos, anchos?). Estamos ante un amplio concepto que nos obliga a reaprender lo que hemos hecho por años (como tuvimos que reaprender conceptos al enfrentarnos al Responsive Web Design). Y es que Flexbox no es una propiedad, flexbox es un nuevo modelo de layout (y se viene otro: grid; que hará que exploten más cerebros aún). Pero vamos de lleno al tema.

Qué es flexbox

Flexbox no es una propiedad ni un cojunto de propiedades. Flexbox es un nuevo modelo de layout que viene a incorporarse a los ya existentes en css (se esta trabajando actualmente en nuevo modelo: el grid layout):

  • Block (los elementos aparecen uno debajo de otro ocupando todo el ancho disponible)
  • Inline (los elementos aparecen uno al lado del otro en una linea y saltan a la linea siguiente al ocupar el espacio disponible)
  • Table (los elementos imitan la distribución de una tabla HTML, con filas, encabezados y columnas).
  • Positioned (los elementos pueden romper el flujo y posicionarse en cualquier lugar del documento):

Un modelo de layout es un set de algoritmos que determinan el tamaño y la posición de los elementos con respecto a sus hermanos y ancestros.

¿Qué se puede hacer con flexbox?

Teniendo lo que significa un modelo de layout, con flexbox podemos hacer lo siguiente:

  • Distribuir los elementos en sentido vertical u horizontal
  • Reordenar la aparición de los elementos sobreescribiendo su aparición en el navegador.
  • Ajustar dinámicamente las dimensiones de los elementos para evitar desbordamientos (overflow) respecto a su padre.
  • Redefinir el sentido del flujo de los elementos (hacia arriba, hacia abajo, hacia la izquierda o hacia la derecha).
  • Alinear los elementos respecto al padre o respecto a sus hermanos.

Soporte de los navegadores

El soporte es al 100% para Firefox, Chrome, Opera (escritorio y moviles) e IE11. Los únicos navegadores que dan problemas son los culpables de siempre: IE y Safari.

  • Safari (escritorio y movil) requiere el prefijo -webkit-
  • IE10 soporta flexbox con el prefijo -ms- pero con la sintaxis del 2012 (se indicará en los ejemplos de este artículo)
  • IE9- no soportan flexbox. Así que si por alguna extraña razón necesitas dar soporte a esos navegadores, sube a tu Delorian y viaja al pasado.

Compatibilidad flexbox

Por otro lado, estamos a casi un mes del lanzamiento de Windows 10 y Su nuevo navegador Edge (que remplazará definitivamente a IE) por lo que es momento de usar Flexbox.

Flex container y flex items

Lo primero que debes saber sobre Flexbox, es que para funcionar necesita que se defina un contexto. Para usar flexbox debes trabajar en conjunto con el contenedor y sus hijos. No hay forma de manipular directamente un elemento con flexbox sin crear antes su contexto. La convención es llamar al contenedor: flex-container y a sus hijos: flex-items.

El contexto se define asignando display:flex a un elemento. Eso hace que sus hijos directos se conviertan en flex-items (es decir, cajas flexibles) y puedan manipularse con flexbox. Dicho esto, existen propiedadees que aplican al flex-container y otras que aplican a los flex-items, aunque no vamos a profundizar sobre eso ahora.

Solo recuerda que el flex-container define el contexto para trabajar con flexbox. Usando display:flex se define un contexto de tipo block. En cambio display: flex-inline define un contexto del tipo inline (con el espaciado característico de los elementos inline e inline-block).

Además a los flex-items se les puede asignar display:flex con lo que se definiría un nuevo contexto en cada uno para sus hijos. No hay limite para este tipo de anidación.


display: flex | inline-flex;
/*
  display: -ms-flexbox | -ms-inline-flexbox (IE10)
  display: -webkit-flex (Safari)
*/

Consideraciones con el flex-container y los flex-items

  • Un texto incluido directamente en un flex-container es envuelto en un flex-item anónimo. Salvo que el texto sea solo espacios, en ese caso, es lo mismo que si tuviera display: none;
  • Float and clear no aplican a los flex-items.
  • Vertical-align no aplica a los flex-items
  • Ls propiedades de columnas column-* no aplican en el flex-container.

Main Axis y Cross Axis

Lo segundo que debes saber es que al definir un contexto para flexbox, internamente cambian muchas cosas, aunque no las puedas ver. Lo principal es que se crean dos ejes: el main axis (principal) y el cross axis (secundario). Estos ejes permiten distribuir y alinear los elementos respecto a ellos y mucha gente se confunde sobre este aspecto. Así que mira detenidamente la siguiente imagen (extraida de la especificación de la W3C):

flexbox axis

Como ves, hay dos ejes. Pero no solo eso, sino que cada eje tiene un inicio (start) y un final (end). De manera predeterminada el eje principal (main axis) es horizontal y su sentido es de izquierda a derecha. Y el eje secundario (cross axis) es vertical y su sentido es de arriba hacia abajo. Además, se definen dos nuevas dimensiones que vienen a sustituir (en ciertas circunstancias) al height y width de los flex-items; estas son main size y cross size (relativas a los ejes y que veremos en detalle en otro post).

El sentido de los ejes está determinado por el sentido de la escritura del documento. Algunos idiomas (como los asiáticos) escriben de derecha a izquierda (rtl, right to left) por lo que, en ese caso, el sentido de los ejes será inverso a lo expuesto aqui. Si bien muy pocas veces usarás documentos con dirección rtl no está de más saberlo.

Además, puedes cambiar el eje principal y el sentido usando flex-direction. Es decir, puedes decidir que el main axis sea vertical, o que el sentido sea de derecha a izquierda o de abajo hacia arriba. Esto se consigue con la propiedad flex-direction (aplicada al flex-container).


flex-direction: row (default) | column | row-reverse | column-reverse
/*
  -ms-flex-direction (IE9)
  -webkit-flex-direction (Safari)
*/
/* 
Según el valor indicado, el main axis será:
  row: horizontal, izquierda a derecha
  row-reverse: horizontal, derecha a izquierda
  column: vertical, de arriba hacia abajo
  column-reverse: vertical, de abajo hacia arriba
*/

Ten en cuenta, que los elementos se distribuyen respecto al eje principal y con el sentido de él. Por lo que al cambiar su orientación y sentido, los flex-items se reordenarán. La siguiente imagen lo explica mejor.

flex direction

Distribuir en el main axis con justify-content

Con la propiedad justify-content podemos distribuir el espacio disponible entre los elementos respecto al main axis. Recuerda que el main axis puede ser horizontal o vertical, según como lo hayamos definido con flex-direction. Por lo tanto, es un error común creer que justify-content alinea horizontalmente (también puede hacerlo verticalmente)


justify-content: flex-start (default) | flex-end | center | space-around | space-between
/*
  -ms-flex-pack: start | end | center | justify; (IE10, no existe space-around, justify remplaza a space-between)
  -webkit-justify-content (Safari)
*/
/* Distribución de los elementos en el main axis
  flex-start: al inicio del main axis
  flex-end: al final del main axis
  center: al medio del main axis
  space around: calcula el espacio libre y lo distribuye alrededor de los flex-items
  space-between: calcula el espacio libre y lo distribute entre los flex-items
*/

La siguiente imagen lo explica mejor:

justify content

Alinear en el cross-axis con align-items

La propiedad align-items (aplicada al flex-container) alinea los elementos respecto al cross axis. Nuevamente, recuerda que aunque de manera predeterminada, el cross axis es vertical, podría ser también horizontal, si así lo definimos en flex-direction. Así que también en este caso, es un error decir que align-items se usa para alineación vertical.

El valor por defecto de esta propiedad (si no se la declara) es stretch, que hace que los flex-items ocupen todo el espacio disponible en el cross axis. Siempre que no tengan esa dimensión definida.


align-items: stretch (default) | flex-start | flex-end | center | baseline
/*
  -ms-flex-align (IE10)
  -webkit-align-items (Safari)
*/
/*
Alineación de los elementos en el cross axis
  stretch: los flexitems rellenan todo el espacio disponible en el cross axis (si no se ha definido su dimensión)
  flex-start: al inicio del cross axis
  flex-end: al final del cross axis 
  center: al medio del cross axis
  baseline: toma como referencia la linea base del texto y los elementos inline (como imágenes)
*/

La siguiente imagen lo explica mejor:

align items

Alinear un flex-item unico con align-self

A diferencia de las propiedades ya vistas, align-self se aplica a un flex-item unico y no al flex-container. Esta propiedad permite posicionar un flex-item específico respecto al cross axis. El comportamiento es idéntico al de align-items, la diferencia es que se aplica a un único flex-item.


align-self: auto (default) | flex-start | flex-end | center | baseline | stretch
/*
 -ms-flex-item-align (IE10)
 -webkit-align-self (Safari)
*/

Centrado absoluto con Flexbox

Uno de los mayores retos del CSS tradicional siempre ha sido el centrado absoluto (centrar vertical y horizontalmente). Con flexbox el reto ha desaparecido. Basta aplicar lo aprendido al flex-container:


.flex-container{
  display: flex;
  justify-content: center;
  align-items: center;
}

Dibujar un dado con Flexbox

Este es un interesante y sencillo ejercicio planteado por Landon Schropp y que permite poner a prueba nuestros conocimientos de alineación en el eje principal y en el eje secundario (lo aprendido en este artículo). Puedes ver el artículo original aqui: http://davidwalsh.name/flexbox-dice y una demostración en el siguiente codepen:

See the Pen Flexbox Dice by Landon Schropp (@LandonSchropp) on CodePen.

Esto es solo el inicio

Flexbox es mucho más de lo que hemos visto en este artículo y en otros posts continuaremos desarrollándolo a fondo.

Comentarios de los usuarios

Pregunta a ChatEDT