CSS Flexible Box Layout "Flexibox": Introducción


El Flexible box layout module, más conocido como “flexibox” es una especificación de CSS3 muy útil, que podría cambiar la forma de hacer las interfaces en la web, pero también es uno de las especificaciones que ha tenido más cambios, diferencias entre navegadores y errores de los últimos años.

Básicamente nos deja elegir la forma en que se distribuyen una serie de hijos dentro del contenedor padre. Podemos elegir que sean filas, columnas, que se expandan o contraigan para ocupar el espacio libre y el orden en que se muestran.


Ahora mismo flexibox funciona bien en Chrome (con ciertos peros en la version móvil), Opera y las nuevas Blackberrys. Está previsto que funcione bien en firefox a partir de la versión 22. Seguramente veremos la funcionalidad completa en nuevas versiones de Safari y Android próximamente. Y en Internet Explorer versión 10 funciona a su manera, no siguiendo la versión que parece ser definitiva. En realidad en Firefox anteriores, Safari y Android debería funcionar la versión anterior. Pero hay tantos cambios y problemas que recomiendo no usar flexibox en navegadores que usen la especificación anterior a menos que sea un caso muy sencillo.

Ver la utilidad practica de las diferentes propiedades de flexibox puede ser caótico, así que vamos a trabajar una serie de ejemplos para ver como se combinan en casos prácticos.

En esta entrada vamos a ver cómo hacer un grid dinámico de cajas. Es un caso que nos podemos encontrar muchas veces, mostramos productos, imágenes, botones de opciones,... tenemos un número indefinido de cajas que colocar, y queremos que se ajuste lo mejor posible al ancho disponible que no siempre conocemos. Y después está el problema de las últimas casillas. Si por ejemplo tenemos 14 elementos y la cuadrícula da para filas de 4 columnas, tendremos 3 filas completas y dos elementos sueltos. En nuestro ejemplo vamos a hacer que esos elementos ocupen todo el ancho posible, es decir que cada uno ocupe dos veces el tamaño de los demás elementos.

Lo bueno de que sea flexible es que si aumentamos el ancho de pantalla tendremos 2 filas de 5 elementos y la última de 4, y en el caso de una pantalla muy estrecha (móvil) podríamos tenemos una lista de elementos de 1 en 1 por filas.

Vamos a hacer el ejemplo con unas sencillas cajas, pero podéis imaginar que esto funcionará igual con descripciones de productos, con su foto y su botón de comprar, o con elementos de menú, o cualquier elemento de una web arbitrariamente complejo. El html sería:

<div id="contenedorFlexi">
<div class="item-flexi">
Caja 1
</div>
<div class="item-flexi">
Caja 2
</div>
<div class="item-flexi">
Caja 3
</div>
<div class="item-flexi">
Caja 4
</div>
<div class="item-flexi">
Caja 5
</div>
<div class="item-flexi">
Caja 6
</div>
<div class="item-flexi">
Caja 7
</div>
<div class="item-flexi">
Caja 8
</div>
<div class="item-flexi">
Caja 9
</div>
<div class="item-flexi">
Caja 10
</div>
<div class="item-flexi">
Caja 11
</div>
<div class="item-flexi">
Caja 12
</div>
<div class="item-flexi">
Caja 13
</div>
<div class="item-flexi">
Caja 14
</div>
</div>

Y el css clave sería:

#contenedorFlexi{
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
width: 500px;
margin:0 auto;
background: #eee;
resize: both;
overflow: auto;
}

.item-flexi {
-webkit-flex: 1 0 110px;
flex: 1 0 125px;
background: #00A6C7;
margin: 5px;
}

En el contenedor especificamos que queremos que sea un contenedor de elementos flexibles y cómo queremos que muestre estos elementos, en este caso en fila, y haciendo que envuelva al elemento. En la práctica sirve para que las cajas no ocupen todo el alto (lo previsible cuando trabajamos en modo fila) y que por lo tanto pase a una línea nueva cuando no haya espacio para todos los elementos en una fila.

En la clase de los contenedores hijo se especifica cómo queremos que ocupe el sitio cada elemento (en este caso todos por igual), los tres parámetros de flex son: Si queremos que se extienda, si queremos que se encoja y el ancho deseado. Podemos dar la importancia de extenderse o encojerse de los elementos, un 0 es que no lo permitimos, y cuanto más alto sea tiene prioridad para extenderse o encojerse más para entrar en la cuadrícula que otro elemento que pongamos una cifra menor. Si damos a todos los elementos el mismo número sirve en la práctica para activar o no, en nuestro caso dejamos que se extienda, pero no que se encoja. El tercer parámetro es el tamaño deseado, que en la práctica sirve para decir de cuanto queremos las filas, más que el el ancho efectivo. Por ejemplo estamos poniendo cajas de 110px en un contenedor de 500px (habría que contar los márgenes entre cajas, pero en este caso se ilustra igual sin tenerlo en cuenta) está claro que entran 4 cajas (440px) y sobran 60px, así que pondrá 4 cajas por fila, pero de 125px cada una en la práctica en lugar de 110px para ocupar todo el sitio.

Además se ha añadido al contenedor la opción resize, para que aparezca en la esquina inferior derecha un triángulo y se pueda hacer el contenedor más grande y probar así cómo distribuye flexibox los elementos cuando damos un mayor ancho.


Caja 1
Caja 2
Caja 3
Caja 4
Caja 5
Caja 6
Caja 7
Caja 8
Caja 9
Caja 10
Caja 11
Caja 12
Caja 13
Caja 14


El ejemplo funciona en Chrome (21+), Firefox 22+ (en teoría, no ha salido a fecha de redacción de este artículo) y Opera (12.1+).