¿Que es Flexbox?
Flexbox es una herramienta de modelado CSS muy poderosa que permite lograr una disposición de elementos dinámica y responsiva con muy poco código.
Con Flexbox lo mas importante y pieza central son los contenedores, pues al aplicarle ciertas reglas afectaremos a sus elementos hijos de forma automática.
Para definir un elemento como “Contenedor Flex” debemos utilizar la propiedad CSS “display”.
.contaner{ display: flex; }
<div class="container"> <div class="card"> <h2>Item 1</h2> <p>This is item 1</p> </div> <div class="card"> <h2>Item 2</h2> <p>This is item 2</p> </div> <div class="card"> <h2>Item 3</h2> <p>This is item 3</p> </div> <div class="card"> <h2>Item 4</h2> <p>This is item 4</p> </div> <div class="card"> <h2>Item 5</h2> <p>This is item 5</p> </div> </div>
Orientación o Disposición de los Elementos
Al definir un elemento como contenedor Flex estamos definiendo dos ejes dentro de dicho contenedor, uno principal y otro secundario. Esto es así porque cuando alineamos elementos dentro de un contenedor lo podemos hacer de forma vertical y horizontal. Por lo tanto con Flex lo primero es definir que orientación será la principal para el contenedor. Para hacer esto usaremos la propiedad “flex-direction“, la cuál por default posee el valor “row“, es decir horizontal.
.container { display: flex; flex-direction: row; }
Cuando usamos el contenedor para que funcione como una fila (row) todos los elementos flotaran de izquierda a derecha. Si por el contrario deseamos que nuestro contenedor tenga una orientación vertical y que cada elemento aparezca por debajo del anterior debemos asignarle el valor “column” a la propiedad “flex-direction“.
.container { display:flex; flex-direction: column; }
Otro aspecto importante es el espacio entre cada elemento de un contenedor. Si bien es cierto que esto se ve afectado por el tipo de alineación o justificado que escojamos, tambien es posible definir un espacio por defecto. Esto se logra usando la propiedad “gap” a la cuál podemos asignar valores en pixeles, em o porcentaje.
.container{ display:flex; flex-direction: column; gap:8px }
Alineación de los Elementos
Con Flexbox es muy sencillo justificar los elementos del contenedor ya sea de forma vertical u horizontal. Como lo mencionamos anteriormente, Flexbox proveé dos ejes, uno principal y otro secundario. Le llamamos primario puesto que es en esta orietación que los elementos seran situados uno detras del otro y por su parte el secundario será utilizado para poder alinear los elementos en torno a este eje secundario. De esta manera si para un caso concreto decidimos usar la propiedad “flex-direction” con el valor “row” es decir de forma horizontal, podremos justificar los elementos a través de la propiedad “justify-content” donde podremos elegir de entre multiples posibles valores:
- flex-start – Alinear los elemento al comienzo del contenedor
- flex-end – Alinear los elementos al final del contenedor
- baseline – Alinear los elementos inmediatamente donde comienza el elemento contenedor.
- center – Alinear los elemento al centro
- space-between – Alinear al centro dejando un espacio entre cada elemento hijo
- space-around – Alinear al centro dejando un espacio entre cada elemento y tambien al principio y al final respetar un margen.
- space-evenly – Alinear al centro dejando un espacio de igual tamaño entre cada elemento y tambien al principio y al final.
En la imágen anterior se aprecian los elementos de un contenedor justificados con la propiedad “justify-content” con valor “space-evenly“.
Ahora bien, ademas de justificar los elementos de forma horizontal también podríamos hacerlo de forma vertical usando la propiedad “align-items“. Esta propiedad se encarga de alinear o justificar los elementos en torno al eje secundario y acepta los siguientes posibles valores:
.container{ display: flex; flex-direction: row; justify-content: space-evenly; align-items: flex-end; }
Como se aprecia en el ejemplo el resultado es tener los elementos del contenedor dispuestos en forma horizontal justificados de la misma forma con un espacio equidistante entre cada elemento y alineados verticalmente al final del contenedor.
Wrapping o Envoltura de Elementos
Cuando trabajamos con contenedores cuyo contenido será mayormente dinámico y deseamos que cuando sus elementos sobrepasen el ancho de este salten a una nueva línea es necesario usar “wrapping”. Flexbox provee una propiedad llamada “flex-wrap” que por defecto tiene como valor “nowrap“. De esta manera los elementos se ubicaran sobre la misma línea a pesar de haber superado el ancho del contenedor.
Si deseamos que esto no suceda debemos asignar a esta propiedad el valor “wrap“.
.container{ display: flex; flex-direction: row; justify-content: space-evenly; align-items: flex-end; gap: 8px; flex-wrap: wrap; }
Cuando elegimos este tipo de comportamiento al permitir que los elementos se ajusten en una nueva línea, también desbloqueamos otras propiedades que permiten personalizar mas el aspecto de los elementos y su distribución. Una de estas nuevas propiedades es “align-content“. Esta propiedad permite alinear los elementos del contendor en relación al conjunto de filas que se lograron al aplicar el “wrapping”. Los posibles valores que podemos aplicar a esta propiedad son:
- baseline
- center
- flex-end
- flex-start
Para ilustrar mejor su funcionamiento veamos la diferencia entre elegir “baseline” y “flex-end”:
Encogiendo Elementos
Flexbox permite ajustar el tamaño de los elemento de un contenedor cuando se redimensiona la ventana del navegador. Para esto Flexbox provee la propiedad “flex-shrink“, la cuál solo acepta dos valores “1” o “0”.
.container { display: flex; flex-direction: row; justify-content: space-evenly; align-items: flex-end; gap: 8px; flex-wrap: wrap; flex-shrink:1; }
Otra propiedad muy útil para cuando deseamos que un elemento se alargue y ocupe todo el espacio disponible o de sobra dentro del contenedor es la propiedad “flex-grow”. Si le asignamos a esta el valor “1” dicho elemento ocupará todo el espacio disponible en la fila.
.container .card:nth-of-type(1){ flex-grow: 1; }
Flexbox con Bootstrap
Implementar flexbox a través de bootstrap hace las cosas mucho mas sencillas, puesto que agregando clases a nuestros elementos logramos el mismo resultado que al usar CSS puro. En primer lugar veamos como agregar boostrap a nuestro proyecto. Para esto debemos agregar una referencia a la hoja de estilos de bootstrap a través de un CDN. También es recomendable agregar la referencia a las librerias de JQuery y Popper.
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Flexbox con Bootstrap</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> </head> <body> ... </body> <html>
Ahora implementaremos flexbox utilizando las clases provistas por bootstrap. Como primer paso vamos a agregar un contenedor con una serie de elementos “card” dentro de él.
<div class="container-fluid"> <div class="card bg-dark text-white"> <h5 class="card-header">Item 1</h5> <div class="card-body bg-light text-dark"> <div class="card-title">This is item 1</div> <div class="card-text"></div> </div> </div> <div class="card bg-dark text-white"> <h5 class="card-header">Item 2</h5> <div class="card-body bg-light text-dark"> <div class="card-title">This is item 2</div> <div class="card-text"></div> </div> </div> <div class="card bg-dark text-white"> <h5 class="card-header">Item 3</h5> <div class="card-body bg-light text-dark"> <div class="card-title">This is item 3</div> <div class="card-text"></div> </div> </div> </div>
Por ahora el contenedor tiene agregada la clase “container-fluid” que permite que abarque la totalidad del ancho de la página, pero sus elementos internos no tienen mayores instrucciones de como ser dispuestos. A continuación agregaremos la clase “d-flex” que permitirá controlar los elementos del contenedor tal como lo hicimos con CSS.
<div class="container-fluid d-flex flex-row justify-content-around align-items-center flex-wrap gap-2 flex-shrink-1 flex-grow-1"> <div class="card bg-dark text-white"> <h5 class="card-header">Item 1</h5> <div class="card-body bg-light text-dark"> <div class="card-title">This is item 1</div> <div class="card-text"></div> </div> </div> </div>
En el ejemplo anterior hemos agregado la clase “d-flex” que es equivalente a tener lo siguiente en CSS:
.container{ display: flex; }
También hemos incorporado la clase “flex-row” que es lo equivalente a la propiedad “flow-direction: row“. También hemos indicado que deseamos que los elementos de la fila estén alineados o justificados de forma que exista un espacio equivalente entre ellos a través de la clase “justify-content-around” que equivale a tener “justify-content: space-around” en CSS. Por otra parte hemos alineado los elementos de forma vertical en el eje secundario del contenedor de manera que aparezcan a la mitad del contenedor utilizando la propiedad “align-items-center” que es muy similar a su equivalente en CSS “align-items: center“. Finalmente agregamos la clase “flex-wrap” que permite que los elementos al superar el ancho del contenedor salten hacia una nueva fila al igual que lo hicimos con CSS “flex-wrap: wrap“.
Otras clases de flexbox que resultan muy útiles son por ejemplo “gap-{x}” la cuál tambien agregamos a nuestro contenedor, permite determinar el espacio que existirá entre los elementos, en nuestro caso elegimos “gap-2” puesto que deseamos que existan alrededor de 8px entre cada elemento del contenedor. Esto sería equivalente a tener un CSS con “gap: 8px” .
Por último agregamos las propiedades “flex-shrink-1” y “flex-grow-1” que permiten encoger los elementos al redimensionar la ventana y abarcar el espacio disponible no utilizado del contenedor respectivamente.
Para mas información te recomiendo ir a la documentación oficial de bootstrap, happy coding!.