Como su propio nombre indica, una de las características más interesantes de flex es la flexibilidad de sus elementos. Existen una serie de propiedades muy interesantes para dotar de interacción y flexibilidad a los elementos que forman parte de un contenedor flex.
A excepción de la propiedad align-self
vista en temas anteriores, todas las propiedades que hemos visto hasta ahora se aplican sobre el elemento contenedor. Las siguientes propiedades, sin embargo, se aplican sobre los elementos hijos.
Propiedades de flexibilidad
Las siguientes propiedades nos permiten dotar de flexibilidad a los elementos hijos de un contenedor flex:
Propiedad | Valor | Descripción |
---|---|---|
flex-basis | Tamaño base de los ítems antes de aplicar una variación. | |
flex-grow | 0 | | Número que indica el factor de crecimiento del ítem (si no ocupa el 100% del padre). |
flex-shrink | 1 | | Número que indica el factor de decrecimiento del ítem (si ocupa el 100% del padre). |
Vamos a ver detalladamente cada una de estas propiedades para entenderlas mejor.
La propiedad flex-basis
En primer lugar, tenemos la propiedad flex-basis
, que define el tamaño base por defecto que tendrán los ítems antes de aplicarle una cierta distribución de espacio. Se suele aplicar un tamaño específico (unidades, porcentajes, etc...), pero también se puede aplicar la palabra clave content
que ajusta automáticamente el tamaño al contenido del elemento. Este es el valor por defecto de la propiedad.
.container {
display: flex;
justify-content: center;
align-items: center;
background: grey;
height: 150px;
gap: 20px;
}
.item {
flex-basis: 200px;
background: red;
}
<div class="container">
<div class="item">Elemento 1</div>
<div class="item">Elemento 2</div>
<div class="item">Elemento 3</div>
</div>
Un detalle interesante sobre esta propiedad, es que si le aplicamos un flex-direction: column
y aumentamos el height
, invertiremos los ejes primario y secundario, y flex-basis
actuará como height
en lugar de como width
. Observa también que al estar usando la propiedad de atajo gap
, el hueco se aplica a ambos ejes, por lo que también actua.
La propiedad flex-grow
La propiedad flex-grow
actúa en situaciones donde:
- Hay un
flex-basis
definido. - Los ítems cubren el tamaño total del contenedor flex padre.
En esas situaciones, la propiedad flex-grow
indica el factor de crecimiento de los ítems en el caso de que no tengan un ancho o alto específico. Modifiquemos el ejemplo anterior y añadamos el siguiente fragmento de código:
.item:nth-child(1) { flex-grow: 1; }
Por omisión, todos los elementos tienen un flew-grow: 0
definido, de modo que no hay factor de crecimiento en el elemento, y tendrá el tamaño definido por la propiedad flex-basis
que explicamos anteriormente. Sin embargo, si colocamos un flex-grow: 1
al primer hijo (ejemplo anterior), este crecerá hasta que la suma de los hijos ocupen el 100% del contenedor, mientras que el resto de hijos tendrá el tamaño base definido por flex-basis
.
Volvamos a modificarlo. Ahora añadiremos las dos últimas líneas de CSS:
.container {
display: flex;
justify-content: center;
align-items: center;
background: grey;
height: 150px;
gap: 20px;
}
.item {
flex-basis: 200px;
background: red;
}
.item:nth-child(1) { flex-grow: 1; }
.item:nth-child(2) { flex-grow: 2; }
<div class="container">
<div class="item">Elemento 1</div>
<div class="item">Elemento 2</div>
<div class="item">Elemento 3</div>
</div>
En este caso, el primer elemento tiene un factor de crecimiento de 1
, mientras el segundo elemento tiene un factor de crecimiento de 2, el resto de elementos tendrán un factor de crecimiento de 0
, o sea, no crecen. Así pues, tendremos que el elemento número 3 tiene un tamaño igual al flex-basis
, mientras que el elemento número 1 crece un poco más y el elemento número 2 crece un poco más que el número 1.
En resumen,
flex-grow
establece un factor de crecimiento observando en conjunto el resto de elementos, y veremos que actua siempre y cuando la suma del espacio de los elementos hijos no superen el 100% del contenedor padre.
La propiedad flex-shrink
Por otro lado, tenemos la propiedad flex-shrink
que es la opuesta a la propiedad flex-grow
. Mientras que la anterior indica un factor de crecimiento, flex-shrink
hace justo lo contrario: aplica un factor de decrecimiento.
La propiedad flex-shrink
actúa en situaciones donde:
- Hay un
flex-basis
definido. - Los ítems no cubren el tamaño total del contenedor flex padre.
Volvamos al ejemplo inicial de flex-basis
y vamos a añadir las dos últimas líneas y a cambiar el flex-basis
de .item
:
.container {
display: flex;
justify-content: center;
align-items: center;
background: grey;
height: 150px;
gap: 20px;
}
.item {
flex-basis: 600px;
background: red;
}
.item:nth-child(1) { flex-shrink: 2; }
.item:nth-child(2) { flex-shrink: 6; }
<div class="container">
<div class="item">Elemento 1</div>
<div class="item">Elemento 2</div>
<div class="item">Elemento 3</div>
</div>
Observa que ahora, hemos definido un flex-basis
más grande, para obligar que ocupe más del 100% del contenedor flex padre. Si al primer elemento le aplicamos un flex-shrink: 2
y al segundo elemento un flex-shrink: 6
, veremos que el primer elemento va a ser ligeramente más pequeño que el tercero (que no cambia respecto al tamaño base), mientras que el segundo elemento va a ser considerablemente más pequeño.
Atajo: La propiedad flex
Existe una propiedad denominada flex
que sirve de atajo para estas tres propiedades indicadas en los ítems hijos. Veamos como funciona, ya que se trata de una propiedad muy versátil que soporta varios formatos:
Propiedad | Valor | Descripción |
---|---|---|
flex (1 parámetro) | none | | Establece un tamaño base o un factor de crecimiento. |
flex (2 parámetros) | Establece un factor de crecimiento y un factor de decrecimiento. | |
flex (3 parámetros) | 0 1 auto | | Establece el factor de crecimiento y decrecimiento y el tamaño base. |
Dependiendo de la cantidad de parámetros:
Si en la propiedad
flex
indicamos un sólo parámetro podemos indicar la palabra clavenone
, que es equivalente a0 0 auto
, podemos establecer unflex-grow
si lo que escribimos es uno en otro caso, podemos escribir un y definir un flex-basis
.Si en la propiedad
flex
indicamos dos parámetros estaremos estableciendo un factor de crecimiento y luego, el factor de decrecimiento.Si en la propiedad
flex
indicamos tres parámetros estaremos estableciendo los dos factores de crecimiento, y además un tamaño base.
Por defecto, el valor por omisión de esta propiedad es 0 1 auto
.
.item {
/* flex: <flex-grow> <flex-shrink> <flex-basis> */
flex: 1 3 35%;
/* Equivalente a... */
flex-grow: 1;
flex-shrink: 3;
flex-basis: 35%;
}
Elementos flex animados
Ten en cuenta que las propiedades flex-grow
, flex-shrink
o incluso su atajo flex
son animables, por lo que podemos conseguir hermosos efectos de animación con fragmentos de código con muy poco código como el siguiente:
.container {
display: flex;
justify-content: center;
align-items: center;
height: 150px;
gap: 5px;
background: grey;
}
.item {
flex: 0 1 15%;
padding: 20px;
background: black;
color: white;
transition: all 0.5s;
}
.item:hover {
flex: 1 1 10%;
background: indigo;
}
<p>Mueve el ratón sobre los elementos:</p>
<div class="container">
<div class="item">Elemento 1</div>
<div class="item">Elemento 2</div>
<div class="item">Elemento 3</div>
</div>
Observa que el truco está en utilizar la propiedad transition
, que veremos en el apartado de Transiciones, en todos los elementos hijos para preparar una animación cada vez que hagamos el :hover
y movamos el ratón sobre un elemento que cambia sus valores de flexibilidad mediante flex
y su color de fondo mediante background
.