El módulo Flexbox de CSS3

Flexbox es un módulo de CSS3 que permite crear layouts flexibles de una forma más eficiente controlando la alineación de las cajas, el ancho y el alto para ocupar el espacio disponible. Un ejemplo simple es que con flexbox puedes hacer que todas las columnas de un sitio tengan el mismo alto y hasta hacer el responsive design mucho más fácil.

Características principales de Flexbox

Algunas de las propiedades de Flexbox se deben aplicar al elemento padre (llamado flex container) y otros deben ser aplicados a los elementos hijos (llamados flex items).

En un layout flex tenés propiedades main y propiedades cross, entre las main están el main size, main axis, main-start y main-end y entre las cross están cross-size, cross-axis, cross-start y cross-end.

  • main size: el ancho o alto del elemento padre creado en base al de los elementos hijos.
  • main-start | main-end: el punto donde empieza y termina el flex content.
  • main axis: es el eje principal del flex container en base a los flex items, este puede ser tanto horizontal como vertical dependiendo de la propiedad justify-content.
  • cross size: es el ancho y alto de los flex items.
  • cross-start | cross-end: el punto donde empiezan y terminan los flex item. Este es para todo el grupo no individual, esto es por si el flex content tiene un padding por ejemplo.
  • cross axis: es el eje perpendicular al main axis y por tanto depende de este.

Propiedades de Flexbox

Ahora sí, veamos las propiedades que forman Flexbox.

display: flex | inline-flex (se aplica al flex container)

Esta es la propiedad principal, define cuál elemento es el flex container y si éste es block o inline, al estar definido habilita el contexto flex a todos sus elementos hijos.

  • display: otros valores | flex | inline-flex;

La propiedad column de CSS no afecta a un flex container. float, clear y vertical-aling tampoco afecta a un flex container.

flex-direction (se aplica al flex container)

Establece el main axis definiendo por tanto la dirección en la que los flex item se ubican.

  • flex-direction: row | row-reverse | column | column-reverse
  • row (default): los elementos se ubican uno al lado de otro siguiendo el mismo orden que tienen en el HTML.
  • row-reverse: los elementos se ubican en el orden contrario al del HTML.
  • column: los elemento se ubican uno debajo de otro en el mismo orden que tienen en el HTML.
  • column-reverse: similar a row-reverse.

flex-wrap (se aplica al flex container)

Define si el flex container es multilinea o de una sola línea y la dirección del cross axis.

  • flex-wrap: nowrap | wrap | wrap-reverse;
  • nowrap (default): de una línea.
  • wrap: multilínea (causa el mismo efecto que poner column).
  • wrap-reverse: multilínea invertido (como column-reverse).

flex-flow (se aplica al flex container)

Esta es una forma abreviada de flex-direction y flex-wrap para definir el main axis y cross axis juntos. El valor por defecto es “row nowrap”.

  • flex-flow: flex-direction flex-wrap;

justify-content (se aplica al flex container)

Define el alineamiento a lo largo del main axis. Ayuda a distribuir los restos de espacio libre adicional cuando todos los flex items en una línea alcanzaron su tamaño máximo.

  • justify-content: flex-start | flex-end | center | space-between | space-around;
  • flex-start (default): los flex items están ubicado en el punto main-start.
  • flex-end: los flex item están ubicado en el punto main-end.
  • center: los flex item están centrados en el main axis.
  • space-between: los flex item estan distribuidos de forma que el primero esté en el main-start y el último en el main-end.
  • space-around: los flex item están distribuidos con espacios iguales entre ellos.

align-items (se aplica al flex-container)

Define el alineamiento a lo largo del cross-axis, piensa en justifiy-content en versión para el cross axis (perpendicular al main axis).

  • aling-items: flex-start | flex-end | center | baseline | stretch;
  • flex-start: similar al de justify-content pero sobre el cross-start.
  • flex-end: como el de justify-content pero sobre el cross-end.
  • center: los alinea de forma centrado según el cross axis.
  • baseline: los flex item están alineados de forma que sus baseline se alinean.
  • stratch (default): los flex item llenan el contenedor (se respeta siempre cualquier min/max aplicado).

align-content (se aplica al flex container)

Este funciona exactamente igual que justify-content, pero sobre el cross axis permitiéndote definir qué hacer con el espacio que sobra. Esta propiedad no surte efecto cuando flexbox es de solo una línea.

  • align-content: flex-start | flex-end | center | space-between | space-around | stretch;
  • flex-start: las líneas se ubican al principio del contenedor.
  • flex-end: las líneas se ubican al final del contenedor.
  • center: las lineas se centran en el contenedor.
  • space-between: las primera queda al principio del contenedor, la última al final, el resto separadas por la misma cantidad de espacio.
  • space-around: las líneas quedan todas separadas por la misma cantidad de espacio.
  • stretch: las líneas ocupan el tamaño restante.

order (se aplica a los flex item)

Por defecto los flex item se ubican según el orden que tienen en el HTML. La propiedad order te permite tomar el controlar del orden en que estos aparecen en el contenedor.

  • order: <entero>;

flex-grow (se aplica a los flex item)

Define la capacidad de los flex item de crecer si es necesario, esto dicta la cantidad de espacio que pueden tomar dentro del contenedor. Si todos los item tienen flex-grow en 1, todos los flex item van a tener el mismo tamaño dentro del flex container. Si uno de los flex item tiene un valor de 2, este ocupará el doble de tamaño que los demás.

  • flex-grow: <número> (default 0);

Los número negativos no son válidos.

flex-shrink (se aplica a los flex item)

Define la capacidad de los flex item de encogerse si es necesario.

  • flex-shrink: <número> (default 1);

Los número negativos no son válidos.

flex-basis (se aplica a los flex item)

Define el tamaño por defecto de los elementos antes de que el espacio restante se distribuya.

  • flex-basis: <tamaño> | auto (default auto);

flex (se aplica a los flex item)

Es la forma abreviada de flex-grow, flex-shrink y flex-basis. El segundo y tercer parámetro (flex-shrink y flex-basis) son opcionales. Por defecto es “0 1 auto”.

  • flex: none | flex-grow flex-shrink flex-basis

align-self (se aplica a los flex item)

Esta propiedad permite sobreescribir para un flex item en particular el alineamiento dado por align-items.

  • aling-selft: auto | flex-start | flex-end | center | baseline | stretch;

Ejemplo de un layout con Flexbox

Acá les dejo un código para que vean cómo funciona usando (casi) todas las propiedades de flex:

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta author="Sergio Daniel Xalambrí" />
    <meta name="description" content="Layout estilo blog usando Flex" />
    <title>Flex Blog Layout</title>
    <meta
      name="viewport"
      content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"
    />
    <link
      rel="stylesheet"
      href="normalize.css"
      type="text/css"
      media="screen"
    />
    <link rel="stylesheet" href="main.css" type="text/css" media="screen" />
  </head>
  <body>
    <header>
      <h1>
        Flex Blog Layout
      </h1>
    </header>

    <div id="wrapper">
      <aside>
        <div>
          <h2>Widget 1</h2>
        </div>
        <div>
          <h2>Widget 2</h2>
        </div>
        <div>
          <h2>Widget 3</h2>
        </div>
        <div>
          <h2>Widget 4</h2>
        </div>
        <div>
          <h2>Widget 5</h2>
        </div>
      </aside>

      <section>
        <article>
          <h2>Post 1</h2>
          <p>
            Normally, both your asses would be dead as fucking fried chicken,
            but you happen to pull this shit while I'm in a transitional period
            so I don't wanna kill you, I wanna help you. But I can't give you
            this case, it don't belong to me. Besides, I've already been through
            too much shit this morning over this case to hand it over to your
            dumb ass.
          </p>
          <p>
            Do you see any Teletubbies in here? Do you see a slender plastic tag
            clipped to my shirt with my name printed on it? Do you see a little
            Asian child with a blank expression on his face sitting outside on a
            mechanical helicopter that shakes when you put quarters in it? No?
            Well, that's what you see at a toy store. And you must think you're
            in a toy store, because you're here shopping for an infant named
            Jeb.
          </p>
          <p>
            Well, the way they make shows is, they make one show. That show's
            called a pilot. Then they show that show to the people who make
            shows, and on the strength of that one show they decide if they're
            going to make more shows. Some pilots get picked and become
            television programs. Some don't, become nothing. She starred in one
            of the ones that became nothing.
          </p>
        </article>
        <article>
          <h2>Post 2</h2>
          <p>
            You think water moves fast? You should see ice. It moves like it has
            a mind. Like it knows it killed the world once and got a taste for
            murder. After the avalanche, it took us a week to climb out. Now, I
            don't know exactly when we turned on each other, but I know that
            seven of us survived the slide... and only five made it out. Now we
            took an oath, that I'm breaking now. We said we'd say it was the
            snow that killed the other two, but it wasn't. Nature is lethal but
            it doesn't hold a candle to man.
          </p>

          <p>
            Look, just because I don't be givin' no man a foot massage don't
            make it right for Marsellus to throw Antwone into a glass
            motherfuckin' house, fuckin' up the way the nigger talks.
            Motherfucker do that shit to me, he better paralyze my ass, 'cause
            I'll kill the motherfucker, know what I'm sayin'?
          </p>

          <p>
            My money's in that office, right? If she start giving me some
            bullshit about it ain't there, and we got to go someplace else and
            get it, I'm gonna shoot you in the head then and there. Then I'm
            gonna shoot that bitch in the kneecaps, find out where my goddamn
            money is. She gonna tell me too. Hey, look at me when I'm talking to
            you, motherfucker. You listen: we go in there, and that nigga
            Winston or anybody else is in there, you the first motherfucker to
            get shot. You understand?
          </p>
        </article>
      </section>
    </div>

    <footer>
      <p>Desarrollado por <a href="//twitter.com/sergiodxa">@sergiodxa</a></p>
    </footer>
  </body>
</html>
flexbox()
   display -webkit-box
   display -moz-box
   display -ms-flexbox
   display -webkit-flex
   display flex
order()
   -webkit-box-ordinal-group arguments
   -moz-box-ordinal-group arguments
   -ms-flex-order arguments
   -webkit-order arguments
   order arguments

footer
header
   background #b2b2b2
   overflow hidden
   padding 10px
   text-align center

footer
   line-height 25px

h1
   margin 0

header
   line-height 75px

#wrapper
   display -webkit-box
   display -moz-box
   display -ms-flexbox
   display -webkit-flex
   display flex
   flex-flow row

   aside
   section
      display -webkit-box
      display -moz-box
      display -ms-flexbox
      display -webkit-flex
      display flex
      flex-grow 1
      article
      div
         color #fdfdfd
         background #666666
         flex-grow 1
         margin 10px
         padding 5px
         h2
            margin 0
         p
            margin 5px 0

   aside
      flex-flow column
      background #cccccc
      width 25%

   section
      flex-flow row
      width 75%

@media screen and (max-width: 1000px) and (min-width: 640px)
   #wrapper
      section
         flex-flow column

@media screen and (max-width: 640px)
   #wrapper
      flex-flow column
      aside
         -webkit-box-ordinal-group 2
         -moz-box-ordinal-group 2
         -ms-flex-order 2
         -webkit-order 2
         order 2
         width auto
      section
         flex-flow column
         -webkit-box-ordinal-group 1
         -moz-box-ordinal-group 1
         -ms-flex-order 1
         -webkit-order 1
         order 1
         width auto

Repositorio en Github

Demo

Soporte de navegadores

Vamos a la parte más importante: qué navegadores lo soportan para saber si se puede usar:

  • Chrome: hasta la versión 20 usando display: box y desde la versión 21 usando display: flex.
  • Safari: desde las 3.1 usando display: box.
  • Firefox: de la 2 a la 21 usando display: box y desde la 22 usando display: flex.
  • Opera: desde la 12.1 usando display: flex.
  • IE: desde la 10 usando display: flexbox.
  • Android browser: desde la 2.1 usando display: box.
  • Safari mobile: desde la 3.2 usando display: box.
  • Blackberry browser: desde la 10 usando display: flex.

Para más información acá esta el línk a Can I Use:

https://caniuse.com/#feat=flexbox

Y para terminar unos mixins hechos en Stylus para ayudarte a que funcione sin problemas.

flexbox()
   display -webkit-box
   display -moz-box
   display -ms-flexbox
   display -webkit-flex
   display flex
flex()
   -webkit-box-flex arguments
   -moz-box-flex arguments
   -ms-flex arguments
   flex arguments
order()
   -webkit-box-ordinal-group arguments
   -moz-box-ordinal-group arguments
   -ms-flex-order arguments
   -webkit-order arguments
   order arguments

Más información: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes