Flexbox: los hijos

Los bloques hijos dentro de un contenedor flexbox poseen sus características propias que permiten, por ejemplo, cambiar el orden en que se colocan (order), asi como especificar el espacio que ocupan dentro de su contenedor o su alineamiento. Al menos a lo largo del eje principal, algo similar a width en layout horizontales (row) o a la altura en despliegues vertivales (column).

Incluso podemos lograr que cada hijo crezca (grow) o se reduzca (shrink) para ocupar todo el espacio disponible en su contenedor. Si la flex-direction es row puede controlarse el ancho del hijo, mientras que si es column se controla el alto. Auqnue siempre puedes usar las propiedades width y height, pero se recomienda utillizar las provistas por el modelo flexbox.

En cualquier caso recuerda que los tamaños de los bloques que vas a gestionar con los estilos CSS se refieren al espacio completo a lo largo del eje principal, y para eso dispones de tres propiedaes flex-basis, flex-grow y flex-shrink.

La caja flexbox
Los items hijos tienen su propias propiedades CSS y algunas que sobreescriben las del felx al que pertenecen

Tamaños: anchuras/alturas

Los tamaños controlables en el modelo flexbox son los que van a lo largo del eje principal es decir el main-size de cada hijo. Si se usa la distribución horizontal (flex-direction: row) este tamaño corresponde al ancho (width). Si se está usando el modelo vertical (flex-direction: column) el tamaño especificado se correcponde con la altura (height).

Los bloques dentro de un contenedor flexbox ocupan el tamaño ajustado al contenido por defecto, si quieres cambiar este comportamiento se usa la propiedad flex-basis. Puedes verlo con este ejemplo, que puedes editar en el sandbox

<head>

<style>

.cajaHor{

display:flex;

border: 1px solid blue;

}

.cajaVer{

display:flex;

flex-direction: column;

border: 1px solid blue;

}

.cajaHor div{

background-color: aqua;

margin: 2px;

}

.cajaVer div{

background-color: aqua;

margin: 2px;

}</style>

</head>

<body>

<p>Bloques dispuestos en filas</p>

<div class="cajaHor" >

  <div>Hijo 1</div>

  <div>Hijo 2</div>

</div>

<p>Bloques dispuestos en columnas</p>

<div class="cajaVer" >

  <div>Hijo 1</div>

  <div>Hijo 2</div>

  </div>

</div>

</body>

Puedes observar que los bloques ocupan el espacio a lo largo del eje principal (main-size) ajustado al contenido, es el comprotamiento por defecto, se corresponde con la propiedad flex-basis:auto. Mientras que la otra dimensión se extiende hasta ocupar el espacio del eje transversal (cross-size).

Los valroes de flex-basis son similares a los de width o height: un número con unidad o un porcentaje respecto del contenedor. Vemos ahora el uso de esta propiedad en este otro ejemplo que puedes probar en el sandbox

<head>

<style>

.cajaHor{

display:flex;

border: 1px solid blue;

}

.cajaVer{

display:flex;

flex-direction: column;

border: 1px solid blue;

}

.cajaHor div{

flex-basis: 150px;

background-color: aqua;

margin: 2px;

}

.cajaVer div{

flex-basis: 150px;

background-color: aqua;

margin: 2px;

}

</style>

</head>

<body>

<p>Bloques dispuestos en filas</p>

<div class="cajaHor" >

  <div>Hijo 1</div>

  <div>Hijo 2</div>

</div>

<p>Bloques dispuestos en columnas</p>

<div class="cajaVer" >

  <div>Hijo 1</div>

  <div>Hijo 2</div>

</div>

</body>

En este segundo ejemplo puedes comprobar como flex-basis funciona como un width en el bloque horizontal (hijos dispuestos en filas) y como una altura en el bloque vertical (hijos dispuestos en columna). Recuerda siempre el esquema de la caja del flexbox para los tamaños: main-size y cross-size.

Recuerda que flex box gestiona la disposición de elementos y el espacio ocupado en una fila o en una columna..

Ajustando el espacio ocupado

Si queremos que los hijos ocupen todo el espacio de su contenedor podríamos usar un flex-basis con un porcentaje para cada hijo, en los ejemplos anteriores si ponemos flex-basis: 50% cada hijo ocuparía la mitad del contenedor (la mitad del main-size). si a uno le ponemos 25% y al otro 75%, pues el primero ocupará un tercio y el otro dos tercios del espacio total del contenedor. Es decir da a cada hijo un tamaño proporcinal al tamaño total del contenedor.

<head>

<style>

.cajaHor{

display:flex;

border: 1px solid blue;

}

.cajaHor div{

background-color: aqua;

margin: 2px;

}

</style>

</head>

<body>

<p>Tamaños proporcionales</p>

<div class="cajaHor" >

  <div style="flex-basis: 25%">

  Hijo 1 (un cuarto)

  </div>

  <div style="flex-basis: 75%">

  Hijo 2 (tres cuartos)

  </div>

</div>

</body>

En este ejemplo ves que los tamaños de cada item hijo mantiene la proporción 1 a 4. Con esto se controla el tamaño del item hijo, no se actúa sobre el espacio libre, este se ajusta de manera automática.

Pero el modelo flexbox puede usar otro mecanismo mediante flex-grow y felx-shrink. Un flex-grow distinto de 0 hace que el item tienda a ocupar todo el espacio del contenedor, para ello se le suma el espacio necesario al flex-basis de cada hijo. Si esta propiedad es 1 todos los items crecerán la misma cantidad. Pero si tienen valores diferentes cada hijo crece en proporción a ese valor. Trabaja sobre el espacio no ocupado. Algo similar ocurre con flex-shrink, pero para reducir los tamaños hijos y ajsutarlos al ancho del contenedor.

Es decir que flex-grow reparten el espacio libre entre los items hijos proporcionalmente al valor de flex-grow. Si un hijo tiene flex-grow: 2, se sumará al valor de su flex-basis el doble de espacio que el sumado al que tenga flex-grow: 1. Si editas este ejemplo lo entenderás.

<head>

<style>

.cajaHor{

display:flex;

border: 1px solid blue;

}

.cajaHor div{

background-color: aqua;

margin: 2px;

}

</style>

</head>

<body>

<p>Aqui flex-basis es un anchura</p>

<div class="cajaHor" >

  <div style="flex-grow: 1">

  Hijo 1

  </div>

  <div style="flex-grow: 2">

  Hijo 2

  </div>

  <div style="flex-grow: 1">

  Hijo 3

  </div>

</div>

</body>

Si los items hijos no caben en el contenedor se pueden contraer restándole espacio al valor de flex-basis. Para controlar cuanto se contrae cada uno se usa la propiedad flex-shrink funciona de manera similar pero restándole espacio al flex-basis de cada hijo, de manera proporcioanl al valor de la propiedad. Si un hijo tiene flex-shrink 1 y otro2, el espacio que falta se parte en tres: al primer hijo se le resta una parte y al otro dos partes.

flex-grow y flex-shrink gestionan el espacio necesario para que los items hijos ocupen el contenedor por completo.

Alineaciones

El modelo flexbox maneja las alineaciones de los hijos mediante la propiedad align-items a nivel del contenedor, pero los items hijos pueden sobreescribir ese valor si se usa la propiedad align-self. Esta propiedad puede tomar los valores habituales: flex-start, flex-end, center, baseline, stretch. Y los signficados son los mismos que con align-items, y también se refieren al eje transversal, como puedes ver en este ejemplo:

<head>

<style>

.cajaHor{

display:flex;

align-items: center;

width: 400px;

height:200px;

border: 1px solid black;

}

.cajaHor div{

background-color: aqua;

margin: 1px;

}

</style>

</head>

<body>

<body>

<p>Extender el tamaño de los hijos</p>

<div class="cajaHor" >

<div>Hijo 1</div>

<div>Hijo 2</div>

<div style="align-self: flex-start">

Hijo 3, queda alineado arriba (flex-start)

</div>

</div>

</body>

En el ejemplo el alineamiento de los items hijos está fijado en la definición del bloque padre como alineados al centro, pero el hijo 3 lo alineamos al borde superior.

O sea, en las flex para filas (row) self-align controlan la posición vertical del hijo

Los items hijos tiene su pueden sobre escribir el avalor de align-items

Atajos: flex

Con esta propiedad podemos reunir en un solo valor las propiedades flex-grow, flex-shrink y flex-basis, los dos primeros escritos en ese orden. No es necesario escribir los tres valores.

.blqHijo{

flex-basis: 200px;

flex-grow:0;

flex-shrink: 1;

}

Es equivalente a este otra más corta:

.blqHijo{

flex: 0 1 200px;

}

Por defecto flex-grow y flex-shrink valen 1, mientras flex-basis es auto.

Los métodos abreviados o atajos facilitan la escritura del código.