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.
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%;
flex: 0 0 80px
flex: 1
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 enflex-basis.1: el ítem reclama todo el espacio libre. Si hay varios ítems conflex-grow: 1, ese espacio se divide en partes iguales.2: el ítem recibe el doble del espacio libre que un ítem conflex-grow: 1en 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 suflex-basisaunque desborde.2: el ítem se encoge el doble de rápido que un ítem conflex-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 elwidthoheightdeclarado del ítem, o su tamaño de contenido si no tienewidth/height.0/0%: el ítem parte de cero. Todo su espacio viene deflex-grow. Usado enflex: 1para 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 unwidthflexible (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-grow | flex-shrink | flex-basis | Efecto |
|---|---|---|---|---|
1 | 1 | 1 | 0% | Todos los ítems con flex: 1 = partes iguales |
auto | 1 | 1 | auto | Crece/encoge respetando el tamaño del contenido |
none | 0 | 0 | auto | Ítem completamente rígido |
0 0 200px | 0 | 0 | 200px | Ancho fijo de 200 px |
2 | 2 | 1 | 0% | Crece el doble que un ítem con flex: 1 |
1 0 | 1 | 0 | 0% | Crece pero nunca se encoge |
flex: 1 vs flex: auto
La diferencia es el flex-basis:
flex: 1(1 1 0%): el basis es0%, así que el espacio libre es todo el contenedor. Tres ítems conflex: 1quedan en tercios exactos, sin importar si uno tiene mucho texto y otro poco.flex: auto(1 1 auto): el basis esauto, el ítem parte de su tamaño natural. El espacio libre se distribuye después de reservar el espacio del contenido. Tres ítems conflex: autopueden 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ón | Solución |
|---|---|
| Campo de búsqueda que rellena el espacio disponible en una barra | flex: 1 |
| Logo o botón que no debe deformarse | flex: none o flex: 0 0 <ancho> |
| N columnas de igual ancho sin importar el contenido | flex: 1 en cada una |
| Columnas donde el contenido más largo “tira” más | flex: auto |
| Sidebar fija con contenido flexible | sidebar: flex: 0 0 240px; contenido: flex: 1 |
Notas y gotchas
flex-grow: 0es el default, no1. Un ítem sin ninguna declaración flex no crece. Hay que pedirlo explícitamente.- El reparto de
flex-growes sobre el sobrante, no sobre el total. Ver la sección deflex-grow. - El reparto de
flex-shrinkestá ponderado porflex-basis. Dos ítems conflex-shrink: 1pero distintosflex-basisno se encojen la misma cantidad en px. min-width: autoen los ítems bloquea el encogimiento. Si un ítem no se achica como se espera, probámin-width: 0.- Preferí el shorthand. Escribir
flex-grow: 1suelto no es lo mismo queflex: 1porque elflex-basisresultante difiere. flex-basisvswidth: en el eje principal,flex-basisgana sobrewidth. Los límitesmin-width/max-widthsiguen 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.