Flexbox

Traducción en progreso.

Flexbox es un método de diseño unidimensional para diseñar elementos en filas o columnas. Los artículos se flexionan para llenar espacio adicional y se contraen para caber en espacios más pequeños. En este artículo explicaremos todos sus fundamentos.

Prerrequisitos: Los conceptos básicos de HTML (véase Introducción al HTML) y una idea de cómo funciona el CSS (véase Introducción al CSS).
Objetivo: Aprender a usar el sistema de diseño Flexbox para crear diseños web.

¿Por qué Flexbox?

Durante mucho tiempo, las únicas herramientas confiables compatibles con el navegador cruzado disponibles para crear diseños CSS fueron cosas como flotantes y posicionamiento. Están bien y funcionan, pero de alguna manera también son bastante limitantes y frustrantes.

Los siguientes requisitos de diseño simples son difíciles o imposibles de lograr con tales herramientas, en cualquier forma conveniente y flexible:

  • Centrar verticalmente un bloque de contenido dentro de su padre.
  • Hacer que todos los elementos secundarios de un contenedor ocupen una cantidad igual del ancho / alto disponible, independientemente de cuánto ancho / alto esté disponible.
  • Hacer que todas las columnas en un diseño de columnas múltiples adopten la misma altura incluso si contienen una cantidad diferente de contenido.

Como verás en las secciones siguientes, flexbox hace que muchas tareas de diseño sean mucho más fáciles. ¡Vamos a profundizar!

Presentación de un ejemplo sencillo

En este artículo, te guiaremos a través de una serie de ejercicios para ayudarte a comprender cómo funciona flexbox. Para comenzar, debes hacer una copia local del primer archivo de inicio flexbox0.html de nuestro repositorio de github. Cárgalo en un navegador moderno (como Firefox o Chrome), y echa un vistazo al código en tu editor de código. Puedes verlo en vivo aquí.

Verás que tenemos un elemento <header> con un encabezado de nivel superior dentro de él, y un elemento <section> que contiene tres <article>. Los usaremos para crear un diseño de tres columnas bastante estándar.

Especificar qué elementos colocar como cajas flexibles

Para comenzar, debemos seleccionar qué elementos se deben presentar como cajas flexibles. Para hacer esto, establecemos un valor especial de display en el elemento padre de los elementos que deseas editar. En este caso, queremos diseñar los elementos <article>, por lo que lo configuramos <section> (que se convierte en un contenedor flexible):

section {
  display: flex;
}

El resultado de esto debería ser algo así:

Entonces, esta declaración única nos da todo lo que necesitamos: increíble, ¿verdad? Tenemos nuestro diseño de columnas múltiples con columnas de igual tamaño, y todas las columnas tienen la misma altura. Esto se debe a que los valores predeterminados dados a los elementos flexibles (los elementos secundarios del contenedor flexible) están configurados para resolver problemas comunes como este. Veremos más sobre el tema más adelante.

Nota: También puedes establecer un valor display de inline-flex si deseas diseñar elementos en línea como cajas flexibles.

Un aparte en el modelo flexible

Cuando los elementos se presentan como cajas flexibles, se distribuyen a lo largo de dos ejes:

flex_terms.png

  • El eje principal es el eje que se ejecuta en la dirección en que se colocan los elementos flexibles (por ejemplo, como filas en la página o columnas en la página). El inicio y el final de este eje se denominan inicio principal y final principal.
  • El eje transversal es el eje que corre perpendicular a la dirección en la que se colocan los elementos flexibles. El inicio y el final de este eje se denominan inicio cruzado y final cruzado.
  • El elemento padre que tiene display: flex configurado (el <section> se llama contenedor flexible).
  • Los elementos que se presentan como cajas flexibles dentro del contenedor flexible se denominan elementos flexibles (los elementos <article> de nuestro ejemplo).

Ten en cuenta esta terminología a medida que avances por las secciones posteriores. Siempre puedes consultarlo nuevamente si te confundes con alguno de los términos que se utilizan.

¿Columnas o filas?

Flexbox proporciona una propiedad llamada flex-direction que especifica en qué dirección se ejecuta el eje principal (en qué dirección están dispuestos los hijos de flexbox); de forma predeterminada, esto se establece en fila, por lo que se presentará en una fila en la dirección en que funciona el idioma predeterminado de tu navegador (de izquierda a derecha, en el caso de un navegador en español).

Prueba a añadir la siguiente declaración a tu regla <section>:

flex-direction: column;

Verás que esto vuelve a colocar los elementos en un diseño de columna, al igual que antes de añadir cualquier CSS. Antes de continuar, elimina esta declaración de tu ejemplo.

Nota: También puedes diseñar elementos flexibles en una dirección inversa utilizando los valores row-reverse y column-reverse. ¡Experimenta con estos valores también!

Delimitar

Un problema que surge cuando tienes una cantidad fija de ancho o alto en tu diseño es que eventualmente los hijos de flexbox desbordarán el contenedor, rompiendo el diseño. Echa un vistazo a nuestro ejemplo flexbox-wrap0.html e intenta verlo en vivo (coge una copia local de este archivo si deseas seguir este ejemplo):

Aquí vemos como los hijos salen de su contenedor. Una forma de solucionar esto es añadir la siguiente declaración a tu regla <section>:

flex-wrap: wrap;

Además, añade la siguiente declaración a tu regla <article>:

flex: 200px;

Prueba esto ahora; verás que el diseño se ve mucho mejor con esto incluido:

Ahora tenemos varias filas: hay tantos hijos de flexbox instalados en cada fila como tenga sentido, y cualquier desbordamiento se mueve hacia la siguiente línea. La declaración flex: 200px establecida en los artículos significa que cada uno tendrá al menos 200 px de ancho; discutiremos esta propiedad con más detalle más adelante. También puedes notar que los últimos hijos de la última fila se hacen más anchos para que toda la fila se rellene.

Pero aquí podemos hacer mucho más. En primer lugar, prueba a cambiar el valor de tu propiedad flex-direction a row-reverse; ahora verás que todavía tienes tu diseño de filas múltiples, pero comienza desde la esquina opuesta del navegador ventana y fluye al revés.

Abreviatura de flex-flow

En este punto vale la pena señalar que existe una abreviatura para flex-direction y flex-wrap: flex-flow Así, por ejemplo, puedes reemplazar

flex-direction: row;
flex-wrap: wrap;

con

flex-flow: row wrap;

Dimensionamiento flexible de artículos flexibles

Volvamos ahora a nuestro primer ejemplo y veamos cómo podemos controlar qué proporción de espacio flexible ocupan los elementos. Inicia tu copia local de flexbox0.html o coge una copia de flexbox1.html como un nuevo punto de partida (véalo en vivo).

Primero, añade la siguiente regla al final de tu CSS:

article {
  flex: 1;
}

Este es un valor de proporción sin unidades que dicta la cantidad de espacio disponible a lo largo del eje principal que ocupará cada elemento flexible. En este caso, le estamos dando a cada elemento <article> un valor de 1, lo que significa que todos ocuparán una cantidad igual del espacio libre restante después de que se hayan establecido elementos como el relleno y el margen. Es una proporción, lo que significa que dar a cada elemento flexible un valor de 400000 tendría exactamente el mismo efecto.

Ahora añade la siguiente regla debajo de la anterior:

article:nth-of-type(3) {
  flex: 2;
}

Ahora, cuando actualices, verás que el tercer <article> ocupa el doble del ancho disponible que los otros dos; ahora hay cuatro unidades de proporción disponibles en total. Los primeros dos elementos flexibles tienen uno cada uno, por lo que ocupan 1/4 del espacio disponible cada uno. El tercero tiene dos unidades, por lo que ocupa 2/4 del espacio disponible (o 1/2).

También puedes especificar un valor de tamaño mínimo dentro del valor flexible. Prueba a actualizar tus reglas de artículo existentes de la siguiente manera:

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 2 200px;
}

Básicamente, esto indica que «a cada elemento flexible se le dará primero 200px del espacio disponible. Después de eso, el resto del espacio disponible se repartirá de acuerdo con las unidades de proporción». Prueba a actualizar y verás una diferencia en cómo se comparte el espacio.

El valor real de flexbox se puede ver en su flexibilidad/capacidad de respuesta: si cambias el tamaño de la ventana del navegador o añades otro elemento <article>, el diseño continúa funcionando bien.

flex: forma completa o abreviaturas

flex es una propiedad abreviada que puede especificar hasta tres valores diferentes:

  • El valor de proporción sin unidades que discutimos anteriormente. Esto se puede especificar individualmente usando la propiedad flex-grow.
  • Un segundo valor de proporción sin unidad, flex-shrink, que entra en juego cuando los elementos flexibles están desbordando el contenedor. Esto especifica cuánto de la cantidad desbordada se quita del tamaño de cada elemento flexible, para evitar que desborden el contenedor. Esta es una característica bastante avanzada de flexbox, y no la cubriremos más en este artículo.
  • El valor de tamaño mínimo que discutimos anteriormente. Esto se puede especificar individualmente usando el valor flex-based.

Recomendamos no usar las propiedades de flexión sin abreviar a menos que realmente tengas que hacerlo (por ejemplo, para anular algo establecido previamente). Conducen a que se escriba mucho código adicional, y pueden ser algo confusos.

Alineación horizontal y vertical

También puedes usar las funciones de flexbox para alinear elementos flexibles a lo largo del eje principal o transversal. Exploremos esto mirando un nuevo ejemplo: flex-align0.html (véalo en vivo), que vamos a convertir en una barra de herramientas/botones ordenada y flexible. En este momento verás una barra de menú horizontal, con algunos botones atascados en la esquina superior izquierda.

Primero, coge una copia local de este ejemplo.

Ahora, añade lo siguiente a la parte inferior del CSS del ejemplo:

div {
  display: flex;
  align-artículos: center;
  justify-content: space-around;
}

Actualiza la página y verás que los botones ahora están bien centrados, horizontal y verticalmente. Lo hemos hecho a través de dos nuevas propiedades.

align-items controla dónde se ubican los elementos flexibles en el eje transversal.

  • De forma predeterminada, el valor es stretch, que estira todos los elementos flexibles para llenar el elemento primario en la dirección del eje transversal. Si el padre no tiene un ancho fijo en la dirección del eje transversal, todos los elementos flexibles serán 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 que utilizamos en nuestro código anterior hace que los elementos mantengan sus dimensiones intrínsecas pero se centren a lo largo del eje transversal. Es por eso que los botones de nuestro ejemplo actual están centrados verticalmente.
  • También puedes tener valores como flex-start y flex-end, que alinearán todos los elementos al inicio y al final del eje transversal, respectivamente. Consulta align-items para obtener todos los detalles.

Puedes anular el comportamiento align-items para elementos flexibles individuales aplicándoles la propiedad align-self. Por ejemplo, intenta añadir lo siguiente a tu CSS:

button:first-child {
  align-self: flex-final;
}

Observa qué efecto tiene esto y retíralo nuevamente cuando hayas terminado.

justify-content controla dónde se ubican los elementos flexibles en el eje principal.

  • El valor predeterminado es flex-start, que hace que todos los elementos se asienten al comienzo del eje principal.
  • Puedes usar flex-end para que se sienten al final.
  • center también es un valor para justify-content, y hará que los elementos flexibles se asienten en el centro del eje principal.
  • El valor que hemos usado anteriormente, space-around, es útil: distribuye todos los elementos de manera uniforme a lo largo del eje principal, quedando un poco de espacio en cada extremo.
  • Hay otro valor, space-between, que es muy similar a space-around, excepto que no deja espacio en ninguno de los extremos.

Nos gustaría animarte a jugar con estos valores para ver cómo funcionan antes de continuar.

Ordenar los elementos flexibles

Flexbox también tiene una función para cambiar el orden del diseño de los elementos flexibles, sin afectar el orden de origen. Esta es otra cosa que es imposible de hacer con los métodos de diseño tradicionales.

El código para esto es simple: prueba a añadir el siguiente CSS al código de ejemplo de la barra de controles:

button:first-child {
  order: 1;
}

Actualiza, y ahora verás que el botón «Sonrisa» se ha movido al final del eje principal. Hablemos sobre cómo funciona esto con un poco más de detalle:

  • De manera predeterminada, todos los elementos flexibles tienen un valor order de 0.
  • Los elementos flexibles con valores de orden más altos establecidos en ellos aparecerán más tarde en el orden de visualización que los elementos con valores de orden más bajos.
  • Los artículos flexibles con el mismo valor de pedido aparecerán en su orden de origen. Entonces, si tiene cuatro elementos con valores de orden de 2, 1, 1 y 0 establecidos en ellos, respectivamente, su orden de visualización sería 4 °, 2 °, 3 ° y luego 1 °.
  • El tercer elemento aparece después del segundo porque tiene el mismo valor de orden y está después de él en el orden de origen.

Puedes establecer valores de orden negativos para que los elementos aparezcan antes que los elementos establecidos con 0. Por ejemplo, puedes hacer que aparezca el botón «Blush» al comienzo del eje principal utilizando la siguiente regla:

button:last-child {
  order: -1;
}

Cajas flexibles anidadas

Es posible crear algunos diseños bastante complejos con flexbox. Es perfectamente aceptable configurar un elemento flexible para que también sea un contenedor flexible, de modo que los elementos secundarios también estén dispuestos como cajas flexibles. Echa un vistazo a complex-flexbox.html (ver en vivo).

El HTML para esto es bastante simple. Tenemos un elemento <section> que contiene tres <article>. El tercer <article> contiene tres <div>:

section - article
          article
          article - div - button   
                    div   button
                    div   button
                          button
                          button

Veamos el código que hemos usado para el diseño.

En primer lugar, configuramos los elementos secundarios de <section> para que se presenten como cuadros flexibles.

section {
  display: flex;
}

A continuación, establecemos algunos valores flexibles en los <article>. Presta especial atención a la segunda regla: estamos configurando el tercer <article> para que sus hijos también se presenten como elementos flexibles, pero esta vez los presentamos como una columna.

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 3 200px;
  display: flex;
  flex-flow: column;
}

A continuación, seleccionamos el primer <div>. Primero usamos flex:1 100px; para darle efectivamente una altura mínima de 100 px, luego configuramos sus elementos secundarios (los elementos <button>) para que también se presenten como elementos flexibles. Aquí los colocamos en una fila delimitante y los alineamos en el centro del espacio disponible como lo hicimos en el ejemplo de botón individual que vimos anteriormente.

article:nth-of-type(3) div:first-child {
  flex:1 100px;
  display: flex;
  flex-flow: row wrap;
  align-artículos: center;
  justify-content: space-around;
}

Finalmente, establecemos un tamaño en el botón, pero lo más interesante es que le damos un valor flexible de 1 auto. Esto tiene un efecto muy interesante, que verás si intentas cambiar el tamaño del ancho de la ventana de tu navegador. Los botones ocuparán tanto espacio como puedan y sentarán tantos en la misma línea como puedan, pero cuando ya no puedan caber cómodamente en la misma línea, se desplegarán para crear nuevas líneas.

button {
  flex: 1 auto;
  margin: 5px;
  font-size: 18px;
  line-height: 1.5;
}

Compatibilidad cruzada de los navegadores

La compatibilidad con Flexbox está disponible en la mayoría de los navegadores nuevos: Firefox, Chrome, Opera, Microsoft Edge e Internet Explorer 11, versiones más recientes de Android / iOS, etc. Sin embargo, debes tener en cuenta que todavía hay navegadores más antiguos en uso que no admiten Flexbox (o lo hacen, pero admiten una versión realmente antigua y desactualizada).

Si bien solo estás aprendiendo y experimentando, esto no importa demasiado; sin embargo, si estás considerando usar flexbox en un sitio web real, debes realizar pruebas y asegurarte de que tu experiencia de usuario aún sea aceptable en tantos navegadores como sea posible.

Flexbox es un poco más complicado que algunas características de CSS. Por ejemplo, si a un navegador le falta una sombra paralela de CSS, es probable que el sitio todavía sea utilizable. Sin embargo, no ser compatible con las funciones de flexbox probablemente romperá un diseño por completo, haciéndolo inutilizable.

Discutimos estrategias para superar los problemas de soporte del navegador cruzado en nuestro módulo Prueba del navegador cruzado.

Resumen

Con esto concluye nuestro recorrido por los conceptos básicos de flexbox. Esperamos que te hayas divertido y que juegues con él mientras avanzas en tu aprendizaje. A continuación, veremos otro aspecto importante de los diseños CSS: las cuadrículas CSS.