propiedad CSS vigente

flex

Flexbox

Shorthand que controla cómo un ítem flex crece, se encoge y cuál es su tamaño base en el eje principal. Combina flex-grow, flex-shrink y flex-basis en una sola declaración.

flex es el shorthand que define el comportamiento de un ítem flex dentro de su contenedor: con cuánta fuerza crece para reclamar espacio libre, cuánto se encoge cuando el espacio escasea, y cuál es su tamaño de partida antes de que se aplique esa lógica de distribución. Concentra tres sub-propiedades — flex-grow, flex-shrink y flex-basis — en una sola declaración que el navegador siempre expande a sus tres componentes, por lo que es más fiable escribir el shorthand que las longhands por separado.

La distinción clave que hay que internalizar es que flex-grow y flex-shrink no fijan anchos: reparten el espacio sobrante o faltante en el eje principal. Si el contenedor tiene 600 px y sus dos ítems tienen flex-basis: 200px, el espacio sobrante es 200 px. Un ítem con flex-grow: 1 y otro con flex-grow: 2 no quedan en 1/3 y 2/3 del contenedor — quedan en 200 + 67 px y 200 + 133 px, porque el reparto aplica solo sobre los 200 px libres.

Comprender este mecanismo cambia cómo se razona el layout. flex: 1 no es “que el ítem ocupe el 100 % del contenedor”: es “que el ítem tome todo el espacio libre”. Si hay un solo ítem con flex: 1, el efecto práctico es que llena el espacio disponible. Si hay tres ítems con flex: 1, ese espacio libre se divide en tres partes iguales y cada uno recibe su tercio — pero partiendo desde un flex-basis: 0%, lo que significa que el tamaño de su contenido no influye en el reparto: todos arrancan desde cero y el espacio libre es el total del contenedor.

flex-grow: 0 (por defecto) A B C espacio libre (sin repartir) B con flex-grow: 1 → reclama todo el espacio libre A B (flex-grow: 1) C flex: 1 en los tres → partes iguales (basis: 0%, ignora el contenido) A · flex: 1 B · flex: 1 C · flex: 1 El contenedor tiene 496 px; tres ítems con flex: 1 = ~165 px cada uno

Sintaxis

/* shorthand: flex-grow flex-shrink flex-basis */
flex: 1;            /* 1 1 0%  — patrón "partes iguales" */
flex: auto;         /* 1 1 auto — crece/encoge respetando el contenido */
flex: none;         /* 0 0 auto — ítem completamente rígido */
flex: 0 0 200px;    /* rígido a 200 px */
flex: 2 1 0%;       /* crece el doble que un ítem con flex: 1 */

/* longhands equivalentes (menos recomendado) */
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
Logo
flex: 0 0 80px
Búsqueda
flex: 1
Acciones
flex: 0 0 100px

flex-grow — factor de crecimiento

flex-grow define con qué factor un ítem reclama el espacio libre que sobra en el eje principal después de colocar todos los ítems en su tamaño base. El valor es un número sin unidad (por defecto 0).

  • 0 (por defecto): el ítem no crece. Se queda en su tamaño natural o en flex-basis.
  • 1: el ítem reclama todo el espacio libre. Si hay varios ítems con flex-grow: 1, ese espacio se divide en partes iguales.
  • 2: el ítem recibe el doble del espacio libre que un ítem con flex-grow: 1 en el mismo contenedor.

El punto crítico: flex-grow reparte el sobrante, no el total del contenedor. Si dos ítems tienen flex-basis: 150px en un contenedor de 400 px, el sobrante es 100 px. Con flex-grow: 1 y flex-grow: 1, cada uno recibe 50 px extra → quedan en 200 px cada uno. Con flex-grow: 1 y flex-grow: 3, el primero recibe 25 px y el segundo 75 px.

.barra { display: flex; gap: 8px; }
.logo  { flex-grow: 0; }       /* tamaño fijo */
.input { flex-grow: 1; }       /* crece para llenar el espacio disponible */

Gotcha: flex-grow no tiene efecto si no hay espacio libre

Si los ítems llenan o desbordan el contenedor, flex-grow no tiene ningún efecto visible. Para ver el crecimiento, tiene que haber espacio libre después de colocar todos los ítems en su flex-basis.

flex-shrink — factor de contracción

flex-shrink define cuánto se encoge un ítem cuando los ítems juntos superan el tamaño del contenedor. El valor por defecto es 1 — todos los ítems se encojen proporcionalmente.

  • 1 (por defecto): el ítem puede encogerse. Si el contenedor se queda sin espacio, este ítem cede.
  • 0: el ítem no se encoge nunca. Mantiene su flex-basis aunque desborde.
  • 2: el ítem se encoge el doble de rápido que un ítem con flex-shrink: 1.
.logo {
  flex-shrink: 0;   /* el logo no se deforma aunque el contenedor sea angosto */
  width: 120px;
}
.contenido {
  flex-shrink: 1;   /* cede espacio si hace falta */
}

Gotcha: el reparto de shrink está ponderado por flex-basis

A diferencia de flex-grow, el encogimiento no se distribuye en proporción directa a los factores. Se pondera por el flex-basis de cada ítem. Un ítem con flex-basis: 300px y flex-shrink: 1 cede más espacio absoluto que uno con flex-basis: 100px y flex-shrink: 1, aunque el factor sea idéntico. Este detalle rara vez importa en la práctica diaria, pero explica por qué dos ítems con el mismo flex-shrink pueden achicarse distinto.

Gotcha: el ítem no se encoge por debajo de su min-content

Por defecto, los navegadores aplican min-width: auto a los ítems flex, lo que impide que se encojan por debajo del ancho mínimo de su contenido (por ejemplo, la palabra más larga en un texto). Si un ítem “no se achica” como se espera, revisar si min-width: 0 resuelve el problema — especialmente en ítems con texto o con overflow: hidden.

flex-basis — tamaño base en el eje principal

flex-basis establece el tamaño de partida del ítem en el eje principal, antes de que flex-grow y flex-shrink apliquen sus ajustes. Funciona como width cuando el eje es horizontal, o como height cuando es vertical.

  • auto (por defecto): usa el width o height declarado del ítem, o su tamaño de contenido si no tiene width/height.
  • 0 / 0%: el ítem parte de cero. Todo su espacio viene de flex-grow. Usado en flex: 1 para que los ítems se repartan el contenedor en partes iguales sin que el contenido influya.
  • Longitud (px, %, etc.): tamaño base explícito. Se comporta como un width flexible (puede crecer/encogerse según grow/shrink).
/* flex-basis: auto — el contenido importa */
.item { flex: 1 1 auto; }   /* crece/encoge desde su tamaño natural */

/* flex-basis: 0 — el contenido no importa, el grow reparte todo */
.item { flex: 1 1 0%; }     /* tres ítems así = tres tercios exactos del contenedor */

/* tamaño base fijo */
.sidebar { flex: 0 0 240px; } /* siempre 240 px, no crece ni encoge */

Interacción con width y min-width

flex-basis toma precedencia sobre width en el eje principal. Sin embargo, min-width y max-width siguen actuando como límites absolutos: un ítem no puede encogerse por debajo de su min-width ni crecer más allá de su max-width, sin importar lo que digan flex-shrink y flex-grow. Ver width para más detalles.

Regla de expansión del shorthand

El shorthand flex siempre expande a los tres componentes. Los valores más frecuentes:

flex: …flex-growflex-shrinkflex-basisEfecto
1110%Todos los ítems con flex: 1 = partes iguales
auto11autoCrece/encoge respetando el tamaño del contenido
none00autoÍtem completamente rígido
0 0 200px00200pxAncho fijo de 200 px
2210%Crece el doble que un ítem con flex: 1
1 0100%Crece pero nunca se encoge

flex: 1 vs flex: auto

La diferencia es el flex-basis:

  • flex: 1 (1 1 0%): el basis es 0%, así que el espacio libre es todo el contenedor. Tres ítems con flex: 1 quedan en tercios exactos, sin importar si uno tiene mucho texto y otro poco.
  • flex: auto (1 1 auto): el basis es auto, el ítem parte de su tamaño natural. El espacio libre se distribuye después de reservar el espacio del contenido. Tres ítems con flex: auto pueden quedar en proporciones distintas si tienen contenidos de diferente largo.

Para columnas de igual ancho, usá flex: 1. Para ítems que deben “respirar” según su contenido, usá flex: auto.

Cuándo usar el shorthand vs las longhands

Siempre preferí el shorthand flex. Cuando escribís flex-grow: 1 sin declarar los otros dos, el navegador aplica sus valores iniciales (flex-shrink: 1 y flex-basis: auto), que no son los mismos que los de flex: 1 (flex-basis: 0%). Esto genera diferencias sutiles y difíciles de depurar. El shorthand, en cambio, siempre establece los tres explícitamente.

Cuándo usarlo

SituaciónSolución
Campo de búsqueda que rellena el espacio disponible en una barraflex: 1
Logo o botón que no debe deformarseflex: none o flex: 0 0 <ancho>
N columnas de igual ancho sin importar el contenidoflex: 1 en cada una
Columnas donde el contenido más largo “tira” másflex: auto
Sidebar fija con contenido flexiblesidebar: flex: 0 0 240px; contenido: flex: 1

Notas y gotchas

  • flex-grow: 0 es el default, no 1. Un ítem sin ninguna declaración flex no crece. Hay que pedirlo explícitamente.
  • El reparto de flex-grow es sobre el sobrante, no sobre el total. Ver la sección de flex-grow.
  • El reparto de flex-shrink está ponderado por flex-basis. Dos ítems con flex-shrink: 1 pero distintos flex-basis no se encojen la misma cantidad en px.
  • min-width: auto en los ítems bloquea el encogimiento. Si un ítem no se achica como se espera, probá min-width: 0.
  • Preferí el shorthand. Escribir flex-grow: 1 suelto no es lo mismo que flex: 1 porque el flex-basis resultante difiere.
  • flex-basis vs width: en el eje principal, flex-basis gana sobre width. Los límites min-width/max-width siguen vigentes.

Vigente / legacy

flex y sus sub-propiedades son ampliamente disponibles desde 2015 (baseline widely). No se necesitan prefijos de vendor para código nuevo. La sintaxis antigua (-webkit-flex, -ms-flexbox) pertenece a navegadores que ya no tienen soporte.