¿Por qué flexbox?
Durante mucho tiempo, las únicas herramientas fiables para crear diseños CSS con una alta compatibilidad entre navegadores, fueron los elementos flotantes y el posicionamiento. Cumplen su propósito, pero tienen una funcionalidad bastante limitada.
Con tales herramientas resulta difícil, si no imposible, lograr obtener un diseño de página sencillo y flexible que cumpla con unos requisitos como los siguientes:
- Centrar verticalmente un bloque de contenido dentro de su elemento padre.
- Hacer que todos los elementos secundarios de un contenedor ocupen una cantidad igual del ancho/alto disponible, independientemente del ancho/alto que haya disponible.
- Hacer que todos los elementos en una distribución de columnas múltiples adopten la misma altura incluso si contienen cantidades diferentes de contenido.
Como verás en las secciones siguientes, los elementos flexbox facilitan mucho algunas tareas de distribución de elementos dentro de la página.
Un ejemplo sencillo
En esta unidad te guiaremos por una serie de ejercicios para ayudarte a comprender cómo funcionan los elementos flexbox. En el siguiente ejemplo verás que tenemos un elemento <header>
con un encabezado de nivel superior en él, y un elemento <section>
que contiene tres elementos <article>
. Los usaremos para crear una distribución bastante habitual de tres columnas:
<header> <h1>Comunidad Valenciana</h1> </header> <section> <article> <h2>Alicante</h2> <p>El campus de la Universidad de Alicante se encuentra en San Vicente del Raspeig, limitando al norte con la ciudad de Alicante. Más de 25.000 estudiantes asisten a la Universidad.</p> </article> <article> <h2>Valencia</h2> <p>Valencia es la capital de la Comunidad Valenciana y la tercera ciudad más grande de España después de Madrid y Barcelona, superando los 800.000 habitantes del municipio.</p> </article> <article> <h2>Castellón</h2> <p>La ciudad es conocida por sus festivales de música, entre los que se encuentran: el festival de música alternativa Tanned Tin, el Festival Internacional de Benicàssim, el Arenal Sound y el Rototom Sunsplash Festival, conocido por su música reggae.</p> </article> </section>
html { font-family: sans-serif; } body { margin: 0; } header { background: purple; height: 75px; } h1 { text-align: center; color: white; line-height: 75px; margin: 0; } article { padding: 1%; margin: 1%; background: aqua; }
Ejercicio propuesto: Distribución simple de cajas
Usando el código del ejemplo anterior, crea una nueva página web con un contenido similar. Puedes utilizar el texto que quieras y los colores y fuentes que más te gusten.
Especificar qué elementos serán cajas flexibles
Para comenzar, vamos a seleccionar qué elementos se van a presentar como cajas flexibles. Para ello, establecemos un valor especial de display
en el elemento padre de los elementos que deseas editar. En este caso, queremos distribuir los elementos <article>
, por lo que lo activaremos la propiedad correspondiente en el elemento <section>
(que se convierte en un contenedor flexible):
section { display: flex; }
Esto hace que el elemento <section>
se convierta en contenedor flex, y sus hijos en elementos flexibles. Así, esta declaración única nos da todo lo que necesitamos. Increíble, ¿verdad? Tenemos nuestra distribución en columnas múltiples con columnas de igual tamaño, y todas las columnas tienen la misma altura. Esto se debe a que los valores por defecto que se han asignado a los elementos flexibles (los elementos secundarios del contenedor flexible) están pensados para resolver problemas comunes como este.
Para dejarlo un poco más claro, vamos a observar detenidamente el resultado. El elemento al que le hemos dado un valor de display
de flex
actúa como un elemento a nivel de bloque en términos de cómo interactúa con el resto de la página, pero sus elementos secundarios se presentan como elementos flexibles. También podemos usar un valor de display
de inline-flex
si queremos que los elementos secundarios de un elemento sean elementos flexibles, pero hacer que ese elemento se comporte como un elemento en línea.
Ejercicio propuesto: Cajas flexibles
Añade al ejercicio anterior el código CSS necesario para que todo el contenido dentro del elemento <section> se muestre como cajas flexibles (display: flex) que se muestran de izquierda a derecha, todas ellas con la misma altura.
Como hemos explicado antes, solo tienes que añadir tres líneas de código y ¡solucionado! Dispondrás de cajas flexibles:
section { display: flex; }
El modelo flexible
Cuando los elementos se presentan como cajas flexibles, se distribuyen con respecto a dos ejes:
- El eje principal (main axis) es el eje en el que se colocan los elementos flexibles. El inicio y el final de este eje se denominan inicio principal (main start) y final principal (main end).
- El eje transversal (cross axis) es el eje perpendicular a la dirección en la que se colocan los elementos flexibles. El inicio y el final de este eje se denominan inicio transversal (cross start) y extremo cruzado (cross end).
- El elemento padre que tiene establecido
display: flex
(el elemento<section>
en nuestro ejemplo) se llama contenedor flexible. - Los elementos que se presentan como cajas flexibles dentro del contenedor flexible se denominan elementos flexibles (son los elementos
<article>
de nuestro ejemplo).
¿Filas o columnas?
A los elementos flexbox les podemos aplicar una propiedad llamada flex-direction
que especifica en qué dirección aparece el eje principal, o lo que es lo mismo, en qué dirección estarán dispuestos los elementos hijo de un elemento flexbox. Por defecto, está establecido en el valor row
, por lo que se presentan en una fila en la dirección en que se escribe el idioma predeterminado de tu navegador (de izquierda a derecha, en el caso de un navegador en español).
Ejercicio propuesto: Distribución en una columna
Añade al ejercicio anterior el código CSS necesario para que los elementos dentro de <section> se muestren en una sola columna (flex-direction: column), de forma similar a la distribución que teníamos antes de aplicar el código CSS.
Bastará con utilizar unas pocas líneas de código CSS:
section { display: flex; flex-direction: column; }
Orden inverso
También puedes distribuir elementos flexibles en una dirección inversa utilizando los valores row-reverse
y column-reverse
.
Ejercicio propuesto: Distribución en fila en orden inverso
Partiendo del ejercicio anterior, utiliza el código CSS necesario para que los elementos dentro de <section> se muestren en la misma fila, pero en orden inverso (flex-direction: row-reverse).
Al igual que antes, solo tiene que utilizar unas pocas líneas de código CSS:
section { display: flex; flex-direction: row-reverse; }
Ejercicio propuesto: Distribución en columna en orden inverso
Partiendo del ejercicio anterior, utiliza el código CSS necesario para que los elementos dentro de <section> se muestren en una sola columna, pero en orden inverso (flex-direction: column-reverse).
Al igual que antes, solo tiene que utilizar unas pocas líneas de código CSS:
section { display: flex; flex-direction: column-reverse; }
Ajustar las columnas al tamaño del contenedor
Un problema que surge cuando tienes una cantidad fija de ancho o alto es que los hijos de un elemento flexbox eventualmente desbordan el contenedor y no se ajustan al diseño de nuestra página. Echa un vistazo al ejemplo de este enlace (donde vemos que los elementos hijo se pueden llegar a salir de su contenedor), o fíjate en el resultado que se observa a continuación, donde el ancho de cada columna es muy reducido:
Ejercicio propuesto: Establecer el tamaño de cada columna
Partiendo del ejercicio anterior, utiliza el código CSS necesario para que los elementos dentro de <section> tengan un ancho fijo de 200px.
Una forma de conseguir esto fácilmente es añadir una propiedad más (flex-wrap:wrap) para ser aplicada al elemento <section> y añadir además, la especificación del tamaño (flex:200px) para ser aplicada al elemento <article>:
section { display: flex; flex-wrap: wrap; }
article { ... flex: 200px; }
Observarás que al haber incluido este código CSS, la distribución de tu página resulta mucho más coherente:
Ahora hay varias filas y en cada fila caben tantos elementos hijo de un elemento flexbox como sean necesarios, y cualquier desbordamiento hace saltar el elemento hacia la línea siguiente. La declaración flex: 200px
que hemos establecido en los artículos significa que cada uno tendrá al menos 200 px de ancho. Observa también que los últimos elementos hijo de la última fila se agrandan hasta rellenar toda la fila.
Ejercicio propuesto: Establecer el número de columnas por fila
Partiendo del ejercicio anterior, utiliza el código CSS necesario para que los elementos dentro de <section> se muestren en dos columnas.
Una forma de conseguir esto fácilmente es utilizar la propiedad correspondiente (flex-wrap:wrap) para ser aplicada al elemento <section> y añadir además, la especificación del tamaño especificando el porcentaje (flex:48%) para ser aplicada al elemento <article>:
section { display: flex; flex-wrap: wrap; }
article { ... flex: 48%; }
Observarás que al haber incluido este código CSS, la distribución de tu página resulta mucho más coherente:
Ejercicio propuesto: Orden inverso en cada fila
Partiendo del código anterior, cambia el valor de tu propiedad
flex-direction
arow-reverse
. Ahora verás que todavía tienes tu distribución en diversas filas, pero comienza desde la esquina opuesta de la ventana del navegador y fluye al revés:
section { display: flex; flex-wrap: wrap; flex-direction: row-reverse; }
Ejercicio propuesto: Añadir imágenes y sombras
Usando el código del último ejemplo anterior, añade tres ciudades más (para mostrar al menos 9 ciudades en total) y también inserta una imagen por cada una. Añade sombras al texto y a las cajas y también puedes cambiar los colores y el texto a tu gusto.
El resultado podría ser similar al siguiente (con ancho fijo o con porcentaje):
Alineación horizontal y vertical
También puedes usar las funciones de los elementos flexbox para alinear elementos flexibles sobre el eje principal o transversal. Exploremos este aspecto a partir de un ejemplo nuevo (puedes mirar el resultado aquí), que vamos a convertir en una barra de herramientas/botones ordenada y flexible. En este momento puedes ver una barra de menú horizontal, con algunos botones pegados en línea a la esquina superior izquierda. Si miramos el código HTML, observaremos que simplemente tenemos 5 botones dentro de un bloque <div>:
<div> <button>Smile</button> <button>Laugh</button> <button>Wink</button> <button>Shrug</button> <button>Blush</button> </div>
Si aplicamos algo de código CSS, por ejemplo, utilizando la propiedad align-items
podremos controlar dónde se ubican los ejemplos flexibles del eje transversal:
- Por defecto, el valor es
stretch
, que ensancha todos los elementos flexibles para rellenar el elemento primario en la dirección del eje transversal. Si el elemento padre no tiene un ancho fijo en la dirección del eje transversal, todos los elementos flexibles son tan largos como los elementos flexibles más largos. Así es como nuestro primer ejemplo obtuvo columnas de igual altura por defecto. - El valor
center
mantiene las dimensiones intrínsecas de los elementos pero los centra sobre el eje transversal. - También puedes tener valores como
flex-start
yflex-end
, que alinean todos los elementos al inicio y al final del eje transversal, respectivamente. Consultaalign-items
para conocer todos los detalles al respecto.
Por otro lado, también podemos modificar el valor de la propiedad justify-content
para controlar dónde se ubican los elementos flexibles sobre el eje principal:
- El valor por defecto es
flex-start
, que coloca todos los elementos al comienzo del eje principal. - Puedes usar
flex-end
para que se coloquen al final. center
también es un valor dejustify-content
(para alinear contenido), que coloca los elementos flexibles sobre el centro del eje principal.- El valor
space-around
puede resultar muy útil porque distribuye todos los elementos de manera uniforme sobre el eje principal y deja un poco de espacio en cada extremo. - Hay otro valor,
space-between
, que es muy similar aspace-around
, pero no deja espacio en los extremos.
Ejercicio propuesto: Alineación vertical y distribución uniforme
Partiendo del código anterior de los cinco botones, cambia el valor de las propiedades align-items y justify-content como se indica a continuación. Cambia además el tamaño del bloque <div>, la fuente del texto y añade también alguna sombra al elemento <div> y a los botones y actualiza el contenido del navegador para observar el resultado.
div { display: flex; align-items: center; justify-content: space-around; }