Saltar al contenido

CSS, de a poco

Curso de CSS

Flexbox

Lección 09 de 37 · 4 min

Flexbox acomoda elementos en una fila o en una columna, reparte el espacio que sobra y los alinea sin márgenes calculados a mano.

Ejes y dirección

Con display: flex un elemento pasa a ser un contenedor flex, y sus hijos directos, elementos flex. Los elementos se ordenan sobre el eje principal (main axis). El eje perpendicular a ese es el eje transversal (cross axis).

flex-direction elige el eje principal: row, el valor por defecto, lo pone horizontal, en el sentido del texto; column lo pone vertical, de arriba hacia abajo. gap agrega espacio entre los elementos, nunca contra los bordes del contenedor.

Mové los controles y mirá cómo la flecha del eje principal gira con flex-direction, y con ella lo que mueve cada propiedad de alineación. Las franjas rayadas cubren el espacio real entre los elementos: el gap, más lo que reparta justify-content.

display: flexcolumn · space-between · stretch
08:42
Rosariovía Zárate
Andén3
flex-direction
justify-content
align-items
salida.css
.salida {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: stretch;
gap: 8px;
width: 256px;
height: 192px;
}
salida.html
<div class="flex flex-col justify-between items-stretch gap-2 w-64 h-48">
<div>08:42</div>
<div>Rosario</div>
<div>Andén 3</div>
</div>

Alineación

justify-content reparte el espacio libre sobre el eje principal, y align-items ubica los elementos en el eje transversal. Como siguen a los ejes, con column se intercambian: justify-content pasa a mover en vertical y align-items en horizontal.

Tres elementos en una fila de 300px con cada valor de justify-content. flex-start los agrupa al inicio, center en el centro, space-between pega el primero y el último a los bordes y space-around deja medio espacio en los bordes.
  1. Agruparflex-start · center · flex-endAgrupan los elementos al inicio, en el centro o al final del eje.
  2. Repartirspace-betweenPega el primero y el último a los bordes y reparte el resto del espacio entre ellos.
  3. Rodearspace-aroundLe da a cada elemento el mismo espacio a cada lado, así que en los bordes queda la mitad que entre dos elementos.
  4. EstirarstretchEl valor por defecto de align-items: estira los elementos para llenar el eje transversal, siempre que no tengan un tamaño fijo en ese eje.

align-self cambia la alineación transversal de un solo elemento. En el eje principal no hay equivalente (flexbox ignora justify-self), pero un margen automático hace el trabajo: margin-left: auto absorbe el espacio libre y empuja ese elemento, y los que lo siguen, hasta el final de la fila.

Una barra con el logo y dos enlaces a la izquierda. El botón Salir tiene margin-left: auto: su margen se lleva todo el espacio libre y lo empuja al final de la fila.
barra.css
.barra {
display: flex;
align-items: center;
gap: 8px;
}
.barra .salir {
margin-left: auto; /* va al final de la fila */
}

Cómo crecen los elementos

Cada elemento flex tiene tres propiedades de tamaño, todas sobre el eje principal:

  1. Baseflex-basisEl tamaño de partida. Por defecto auto, que toma su width o, si no tiene, su contenido.
  2. Crecerflex-growQué parte del espacio sobrante se lleva. Por defecto 0: no crece.
  3. Cederflex-shrinkCuánto cede cuando falta lugar. Por defecto 1: todos ceden.

El reparto es proporcional. En un contenedor de 400px sin gap, con dos elementos de flex-basis 100px, sobran 200px; si sus flex-grow son 1 y 3, el primero recibe 50px y el segundo 150px, y terminan midiendo 150px y 250px.

Dos vagones en una fila de 400px, los dos con flex-basis de 100px. Sobran 200px: el primero, con flex-grow 1, crece 50px y mide 150px; el segundo, con flex-grow 3, crece 150px y mide 250px.

El atajo flex: 1 equivale a flex: 1 1 0%: el elemento parte de cero y crece. Por eso varios elementos con flex: 1 quedan del mismo ancho mientras su contenido entre. En la demo, el destino se queda con todo el espacio libre: las franjas vuelven a medir solo el gap y justify-content ya no tiene nada que repartir.

fila.css
.fila {
display: flex;
flex-wrap: wrap; /* lo que no entra baja de línea */
gap: 16px;
}
.fila > * {
flex: 1 1 200px;
min-width: 0; /* deja que el texto se corte */
}

Por defecto todo va en una sola línea (flex-wrap: nowrap); con wrap, los elementos que no entran pasan a la línea siguiente. Y un detalle que confunde: los elementos flex tienen min-width: auto, así que no se achican por debajo de su contenido más largo, como una URL. Para que un texto se corte con text-overflow: ellipsis, poné min-width: 0 en el elemento flex que lo contiene.

En Tailwind

En Tailwind, la clase flex es display: flex, no el atajo flex. Cada valor de alineación tiene su clase, y gap usa la misma escala de 4px que el relleno: gap-2 son 8px.

CSSTailwind
display: flex · inline-flexflex · inline-flex
flex-direction: row · columnflex-row · flex-col
justify-content: space-betweenjustify-between (start, center, around)
align-items · align-self: centeritems-center · self-center
gap: 8px · margin-left: autogap-2 · ml-auto
flex: 1 · flex-shrink: 0flex-1 · shrink-0 · grow · basis-0
flex-wrap: wrap · min-width: 0flex-wrap · min-w-0
contenedor.html
<!-- barra: el logo a la izquierda, las acciones empujadas a la derecha -->
<nav class="flex items-center gap-4">
<a href="/">Logo</a>
<a class="ml-auto" href="/ayuda">Ayuda</a>
<a href="/salir">Salir</a>
</nav>
<!-- columna en el teléfono, fila desde 48rem -->
<div class="flex flex-col gap-4 md:flex-row">
<aside class="md:w-48 md:shrink-0">…</aside>
<main class="min-w-0 md:flex-1">…</main>
</div>