El nuevo Flexbox: flexible box model o modelo flexible de caja. Su layout 4.11.12
Un repaso en profundidad al flexbox o modelo de caja flexible (flexible box model layout). Ojo: usando la nomenclatura y sintaxis actual y vigente, no la antigua ya abandonada por el W3c
El nuevo Flexbox: flexible box model o modelo flexible de caja. Su layout
Última Actualización Marzo 2013
Este nuevo modelo de caja y las herramientas que incorpora significa terminar con la dictadura que imponía hasta la fecha el orden de aparición de los diferentes elementos en el documento origen.
A la vez muchas de las carencias de Css2.1 en el control de las cajas y realización del layout quedan superadas al utilizar el flexbox. Y otras muchas que requerían de ingenio y realizaciones complejas dejan de serlo.
Este artículo es complementario y actualización del ya veterano flexible box model layout escrito en Marzo de este año. Pero enfocado no tanto a trasladar al español el documento del consorcio sobre él sino a que tengas una visión global del flexbox y las posibilidades que trae. Te remito a él para ampliar conceptos y terminología.
Acércate a este modelo de caja sin pretender asimilarlo y dominarlo todo desde el principio. Haz como con con otros aspectos de Css como el box-shadow: primero supiste que se pueden hacer sombras, después descubrirte que puedes controlar hasta 6 aspectos en cada valor, y que puedes definir múltiples valores en la propiedad, y por fin alguien crea un script que reproduce cualquier imagen como la Monalisa y otros.
Ni que decir tiene que la nomenclatura y sintaxis que te vas a encontrar es la actual y no la antigua (ver “Old” Flexbox and “New” Flexbox” de Chris Coyier) y la base del artículo es el documento "CSS Flexible Box Layout Module" con estatus W3C Candidate Recommendation
del 18 de Septiembre de este año.
Sumario
- Soporte de los navegadores al flexbox
- El concepto del Flexbox
- Terminología o vocabulario del flexbox
- Propiedades del Flexbox model
- Propiedades que no aplican al flexbox
- Cómo crear un flexbox
- Ejemplos de uso e ilustrativos de cómo funciona el flexbox
- Artículos relacionados
Soporte de los navegadores 03/2013
- Opera (12.1) - Soporta la última especificación sin necesidad de prefijos privativos.
- Chrome (23.0) - Soporta la última especificación pero necesita su prefijo privativo -webkit-.
- Safari (5.1) - Soporta la vieja especificación pero necesita su prefijo privativo -webkit-.
- Internet Explorer (10) - Soporta la vieja especificación pero necesita su prefijo privativo -ms-. IE9 y menores no le dan soporte
- Firefox (16.0) - Soporta la vieja especificación pero necesita su prefijo privativo -moz-. La versión 20.0 soportará la última especificación sin necesidad de prefijos.
El concepto de Flexbox o caja flexible
Las principales características que definen el diseño flexible son:
- El orden de colocación de los items en la pantalla es independiente del orden de aparición en el Html.
- Los items se liberan de la tiranía de la propiedad direction y unicode-bidi. Esto es:
- La noción de ejes X e Y y su obligado seguimiento queda superado.
- La capacidad de alterar los tamaños de los elementos para rellenar mejor el espacio disponible en cualquier dispositivo de visualización. Una caja flexible expande sus items para llenar el espacio libre disponible, o los reduce para que no haya desbordamientos.
- Otras que tú mismo descubrirás tras jugar con él.
Terminología o vocabulario del flexbox
Debido a que ideas, conceptos y comportamientos establecidos hasta ahora quedan obsoletos o no son de aplicación y que el modelo de caja flexible introduce otros nuevos es conveniente familiarizarse con su terminología.
Para comprenderla mejor, apóyate en el gráfico de abajo:
- Flexibilidad
- Es la capacidad de una caja (flex container) para hacer que sus hijos (flex items) modifiquen sus tamaños para llenar el espacio disponible. Y a la vez distribuir el espacio sobrante entre ellos, alterando, si fuera necesario, las medidas de los items para evitar desbordes o colapsos.
Simultáneamente a lo anterior, la flexibilidad permite establecer qué eje (X-Y) es el principal y cuál es el sentido de flujo de los items en ambos ejes. - Así mismo, la flexibilidad permite alterar el orden de presentación de los items con independencia del lugar que ocupan en el html.
- Flex container:
- La caja contenedora o padre de los elementos flexibles. Para que un elemento se convierta en "flex container" hay que declarar la propiedad display con el valor flex o inline-flex. Más en detalle.
No confundas el valor flex de la propeidad display que se declara en al flex container con la propiedad acortada flex que se usa en los items. - Flex items
- Son los hijos del flex container y sobre los que se aplicará el flexible box model layout. El texto contenido diréctamente en un flex container se envuelve en un flex item anónimo. Pero si el texto es únicamente espacio en blanco no se renderiza, se trata como si tuviese "display: none".
Para ver exáctamente cuándo un elemento se convierte en un flex item y cuando no lee esto. - Axis o ejes
- En cada flex container se definen dos ejes. El eje principal o main axis es el eje a lo largo de la cual los items se ordenan en líneas (ya sean filas o columnas, dependendiente de que sea el eje X o Y el definido como principal). El eje transversal o cross axis es el eje perpendicular al eje principal.
- La propiedad flex-direction define o marca la dirección del eje principal.
- La propiedad justify-content alinea todos los items de la línea actual a lo largo del eje principal.
- La propiedad align-items hace la misma alineación que justify-content pero en el eje transversal. Y la propiedad align-self alinea en el eje transversal los items de manera individual, reescribiendo el valor de "align-items" para ese hijo en concreto.
- Direcciones o sentido de colocación
- Main start/end y cross start/end. La colocación de los items en cada una de las líneas de los dos ejes se pueden ordenar en un sentido u otro de la dirección de cada eje. Si el eje principal es el horizontal (X) se pueden colocar de derecha a izquierda o de izquierda a derecha formando filas. Y si el main axis es el vertical (Y) forman columnas de arriba a abajo o al contrario.
- Líneas
- Los items pueden ser distribuidos en una sólo línea o en varias dentro de su container con la propiedad flex-wrap.
- Tamaños o dimensiones
- En los items no tiene sentido, por lo anterior, hablar de anchuras o alturas (width/height). Sus equivalentes son el "main size" y "cross size" que siguen (orientan) de acuerdo al eje principal y transversal.
- Las propiedades min-height y min-width tienen un nuevo valor: auto que establece el tamaño mínimo del item.
- Flex es la forma acortada de las propiedades que establecen la "flexibilidad" de una caja y sus items.
Propiedades del Flexbox model
A continuación un listado por orden alfabético de las propiedades necesarias para poder usar el nuevo modelo de caja flexible. Son las que controlan todos los aspectos del flexbox o modelo flexible de caja. Recuerda que ésta es la sintaxis actual. Mi opinión es que es la que deberías manejar, con independencia del soporte actual de los navegadores.
No se preveen cambios significativos, por el estatus que te comenté al inicio (candidata para ser la recomendación).
Indico entre (paréntesis e itálicas) a qué elemento se aplica la propiedad seguido de los valores posibles. En los enlaces (que dirigen a la página developer.mozilla.org) de cada una tienes toda la información de ella: los valores admitidos, su significado o qué hacen, el soporte por los diferentes navegadores a cada una, etc. Pincha en las imágenes que las acompañan para verlas bien.
- align-content
- (flex containers que forman múltiples líneas). Valores: flex-start | flex-end | center | space-between | space-around | stretch
- Define cómo se alinean las líneas formadas por los items dentro del contenedor flexible cuando hay espacio adicional en el eje transversal. El valor por defecto es "stretch" que hace a todos los items de la misma "altura" (columnas equilibradas por defecto).
- align-items
- (flex container). Valores: flex-start | flex-end | center | baseline | stretch
- Alinea los items su línea en la dirección perpendicular (eje transversal).
- align-self
- (items) Valores: auto | flex-start | flex-end | center | baseline | stretch
- Alinea un item determinado sobreescribiendo el valor de "align-items"
- display
- (flex container) flex | inline-flex
- Convierte un elemento en un flex container.
- flex
- (items) none | [ 'flex-grow' 'flex-shrink' || 'flex-basis' ]
- Propiedad acortada de flex-basis, flex-grow y flex-shrink:
Son las que hacen posible y en qué forma y proporción los items modifican sus tamaños para ocupar y repartirse el espacio disponible en el flex container. O lo disminuyen para adaptarse a él.- flex-grow: Si hay espacio sobrante en el container determina cuánto de ese espacio ocupará el item respecto a los otros. Es una relación. Así, si tienes 100px sobrantes en el container y tres items con valores de 1, 1 y 2 en flex-grow, los dos primeros crecen 1 parte cada uno de los 100px = 25px cada uno [(100/4)*1], y el tercero 2 = 50px. También se le llama factor o relación de crecimiento.
- flex-shrink: Los items además de poder crecer para repartirse el espacio libre del container también pueden encoger (disminuir su tamaño para evitar desbordes) cuando su flexbox no es lo suficientemente grande. Esta propiedad lo controla de la misma forma que flex-grow.
- flex-basis: El tamaño inicial del item antes de crecer o disminuir en función del espacio de su flex container por las dos propiedades anteriores. Si se omite el valor es cero (0) y el valor "auto" significa que su tamaño está en función de su contenido.
- flex-flow
-
(flex container) Forma acortada de "flex-direction" y "flex-wrap":
- flex-direction: row | row-reverse | column | column-reverse | Especifica cómo se colocan los items en el contenedor flexible definiendo el eje principal y la dirección (normal o invertida/reverse).
- flex-wrap: nowrap | wrap | wrap-reverse | Define si los items se colocan en una o varias líneas
- justify-content
- (flex containers) Valores: flex-start | flex-end | center | space-between | space-around
- Alinea los items en el eje principal de la línea actual. La alineación se realiza después de aplicar los tamaños y los márgenes de los items. Esta propiedad no tiene efecto en flex containers de una sola línea.
- min-height y min-width
- (elementos de bloque y reemplazados)
Valores para las dos: length | percentage | auto | max-content | min-content | fit-content | fill-available - Se usan para establecer la altura/anchura mínima de un elemento dado. Evita que el valor utilizado en height/width de cada item sea menor que el valor especificado para min-height/min-width. Interesante que veas cada una de las palabras clave usadas como valores.
- order
- (items) valores numéricos
- Especifica el orden en que se dibujan los items en su container, con independencia de cómo aparezcan en el html. Los elementos se disponen en orden ascendente según su valor de "order". Los items con el mismo valor en "order" se presentan en el orden en que aparecen en el código fuente.
Propiedades que no aplican al flexbox
- Todas las column-* del módulo de las multicolumnas Css no hacen nada en un flex container.
- float y clear no tienen efecto en los items.
- vertical-align tampoco tiene efecto en los items.
Convertir una caja en un flex container
Lo primero que hay que hacer es indicar que un elemento cree una caja flexible o flexbox. Para ello se usa una de los dos declaraciones siguientes:
section {display: flex;}Crea un flexbox de bloque (block)
article {display: inline-flex;}Crea un flex de línea (inline)
Ejemplos de uso e ilustrativos de cómo funciona el flexbox
Tengamos un html de lo más típico y normal: una página con su cabecera, su sección principal y el pie de página, tal como el siguiente:
<body>
<header>header</header>
<div id='main'>
<article>article</article>
<nav>nav</nav>
<aside>aside</aside>
</div>
<footer>footer</footer>
</body>
Lo siguiente es definir el Css para logar una caja flexible (en el ejemplo el div con id "main") y las propiedades para verse en un sobremesa. Fíjate que el orden en el html es article -> nav -> aside. No incluyo prefijos ni las propiedades "visuales". El resultado es la imagen al lado del css:
#main {
min-height: 800px;
/*creamos el flex container:*/
display: flex;
/*Cómo se disponen los items:*/
flex-flow: row;
/*row= el eje principal coincide con la dirección
del texto. En español horizontal (eje Y) de Izq a drcha*/
}
#main > article {
flex: 3 1 60%;
/*3= flex-grow = factor de crecimiento//
1= flex-shrink = factor de contracción //
60%= flex-basis = el espacio del container
que ocupará el item*/
order: 2;
/*2= se dibujará en segundo lugar,
tras el item que tenga un valor de 1*/
}
#main > nav {
flex: 1 6 20%;
order: 1;
}
#main > aside {
flex: 1 6 20%;
order: 3;
}
El resultado de este css es el que puedes ver en la imagen de abajo. Es una captura de Chrome Canary. Como ves, se ha producido una ordenación de nav, article y aside respecto al html. Y lo mismo con las anchuras. Article ocupa el 60% del espacio de su padre y los otros dos un 20% cada uno. Y el factor de crecimiento de article es de 3 y el de merma 1. Mientras que en los otros estos valores está invertidos: 1 y 6
Y a continuación definimos una media querie pensando en pantallas pequeñas.
@media all and (max-width: 640px) {
#main, #page {
flex-flow: column;
/*cambiamos de filas a columnas*/
}
#main > article, #main > nav, #main > aside {
/* Restablecemos el orden */
order: 0;
}
#main > nav, #main > aside, header, footer {
/*Fijamos alturas*/
min-height: 50px;
max-height: 50px;
}
}
El resultado al ver la página en una ventana del tamaño definido cambia totalmente respecto al anterior: ahora los elementos están uno sobre otro, no al lado formando las 3 columnas. Hemos alterado el orden de "dibujado" de los elementos en la pantalla (order:0) para todos. Con el flexbox ahora podemos poner en el html en primer lugar el elemento principal de la página (article). Así se vería.
Animación de las propiedades flex
No todas las propiedades de este módulo admiten animaciones. Las que sí lo hacen son:
order
flex-grow, flex-shrink: excepto entre el valor 0 y otros
flex-basis: en la medida que lo es la propiedad width
Juega con el flexbox
Si quieres entretenerte un poco con estas propiedades, bájate Chrome Canary. Asegúrate de tener la última versión. Recuerda que debes utilizar los prefijos privativos.
Puedes pasarte por CSS Flexbox Please! o por flexplorer y prueba a variar los valores para ver en vivo qué hace qué y obtener los códigos.
Para cualquier detalle al respecto, nada como el documento del W3c. Aquí tienes de nuevo su enlace: CSS Flexible Box Layout Module. Siempre es bueno tener a mano la fuente original.
03/2013 : El artículo de Adobe en sus blogs "Working with flexbox: The new specification" [ing] tiene un .zip para descargar con ejemplos de realizaciones con el flexbox.
En codepen tienes alguna realización al respecto. Esta incluye la nueva nomenclatura:
En el pen, como ves, su autor comenta cada una de las propiedades y qué hace.
Y ya para terminar, que si has llegado hasta aquí ya tienes mérito, una colección de pens en la que tienes de todo un poco sobre el flexbox: nuevo y viejo/obsoleto.
Y fin
Si conoces otras demos realizadas con el flexbox compártelas en los comentarios. Y si descubres en el artículo algún error, omisión o algún dato poco riguroso házmelo saber. Gracias.
Kseso
the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso
Jo. Llegué a tu página de rebote y casualidad. Qué suerte he tenido.
ResponderEliminarUno de los mejores blogs sobre css en español.
Y este artículo es el mejor, más completo y más actual escrito en español sobre el flexbox.
Gracias.
Henial
EliminarCoincido con Anónimo anterior. Gracias por el efuerzo y por la generosidad de compartirlo.
ResponderEliminarHola me gusta bastante tu blog, quería saber si solo utilizas flexbox para el diseño de tu sitio, o también te ayudas con las medias queries??, Saludos
ResponderEliminarHola Víctor
EliminarUna pizca de @media queries sí uso en el blog.
Pero nada relativo al flexbox. Quizás para la próxima remodelación sí sea un serio candidato a tener en cuenta.
Un saludo
que editor me recomiendas mi netbeans y sublime 3 no me reconoce las propiedades saludos buen blog :)
ResponderEliminarHola Alexis
EliminarPues no te podría recomendar ningún editor. No los conozco tanto como para tener una opinión objetiva. Como digo por algún lado, sólo soy un enredique amanuense de css.
Pero si te estás iniciando en css (o cualquier otro lenguaje) y tu objetivo es aprender soy de los que opinan que lo mejor es un editor que como mucho te coloree el código y así visualices si cometes un error. Pero nunca que lo completen o escriban por ti.
Y especialmente nunca, nunca jamás de los jamases los de interfaz con arrastrar y soltar. Siempre en código.
Pero repito, todo lo anterior si lo que quieres es formarte.
Un saludo y disculpas por el retraso en la respuesta.
Hola buen post gracias por el aporte, también me gusto el diseño, y me gustaría que me aclararas algo al respecto si es posible!, el cuadro de búsqueda o imagen "di amigo y enter"; que se muestra sobre los elementos azul y blanco como superponiéndose entre éstos, lo hiciste con flexbox, o usaste algún otro atributo de css3, html5, javascript, jquery, si me puedes ayudar para investigar esto con mas profundidad te lo agradecería mucho. Soy nueva en ésto y me gustaría aprender un poquito mas cada día :)
ResponderEliminarNo.
EliminarSólo es un form con su input tipo text y su label con algunos estilos para darle la apariencia (incluido un margen superior negativo).
El texto es el valor del atributo placeholder
Puedes ver tanto el marcado html como los estilos asociados con el inspector de código que incorporan todos los navegadores actuales.
Un saludo
Hola:
ResponderEliminarSolo por actualizar el último ejemplo, que es muy bueno pero está desactualizado (solo para Chrome usando "-webkit-"), hice un fork (dando el crédito a su autor) y lo actualicé agregando las instrucciones flex sin -webkit- para que funcione en otros browsers, como Firefox, que si no, no funciona.
Por si te interesa, te dejo el link para que puedas actualizarlo en el artículo y que los demás lo vean bien:
https://codepen.io/fdbozzo/pen/KzRqqW