Déjame decir esto primero: Flexbox es fácil. Ya sea por problemas de adopción temprana o porque hemos aprendido a pensar en términos de flotantes y bloques, a menudo los diseñadores web me dicen que creen que Flexbox es complejo de implementar. Pero repito: flexbox es fácil.
Hay un truco para entender flexbox que te enseñaré, después de lo cual todo estará claro. Pero primero, quiero hablar sobre qué es Flexbox.
Flexbox (o el Módulo de diseño de caja flexible para darle su nombre correcto) es un conjunto de propiedades de CSS que se combinan para diseñar el contenido de una manera receptiva.
Flexbox es la primera técnica de diseño de CSS que funciona para la web moderna. Es justo decir que hasta que se admitió Flexbox, no había una técnica de diseño que funcionara bien con un diseño web receptivo.
Muchos hacks han estado flotando, como establecer elementos para mostrar: bloque en línea y permitir que se envuelvan. Pero esto presentaba una serie de problemas para los sitios flexibles, como la falta de control y el efecto en cadena del cambio de tamaño de los elementos. Por esta razón, muchos sitios web receptivos todavía usan JavaScript para posicionar el contenido.
El W3C describe Flexbox como diseñado para diseñar elementos de IU, como elementos de menú, y no está diseñado para diseñar páginas enteras.
La razón por la que no está destinado a la distribución de páginas enteras, es que flexbox tiene un módulo CSS complementario, el Módulo de diseño de cuadrícula que está destinado para el diseño. El diseño de cuadrícula se considera la técnica más adecuada para diseños de página completa. Lamentablemente, hay un soporte muy limitado para la grilla en este momento, y por "limitado" me refiero a "ninguno". Incluso la última versión de Chrome no puede admitirlo sin indicadores.
Afortunadamente, el soporte de navegador para flexbox es mucho más completo. Y debido a que resuelve tantos problemas de diseño moderno, flexbox es una herramienta ideal hasta que finalmente se adopte la grilla.
Flexbox es ideal para diseñar componentes en una página. El poder real de flexbox, y la razón por la que funciona mucho mejor que otras opciones de diseño, proviene de la declaración de estilos en grupos de elementos en lugar de artículos individuales.
Cuando se trata de diseño, rara vez necesitamos colocar un solo elemento; si tenemos planeado hacerlo, es mucho mejor usar el posicionamiento. Flexbox funciona mejor cuando controla cómo los grupos de elementos se relacionan entre sí.
Siempre diseñe algo considerándolo en su siguiente contexto más amplio: una silla en una habitación, una habitación en una casa, una casa en un ambiente, un ambiente en un plan de la ciudad. - Eliel Saarinen
Como tal, la especificación FlexBox se divide en dos partes, un conjunto de propiedades que hacen referencia al elemento contenedor y un conjunto de propiedades que hacen referencia a los elementos que están dentro.
El soporte del navegador es, por lo general, una pregunta compleja. Hecho aún más complejo para flexbox porque flexbox tiene varias sintaxis diferentes. La indecisión temprana, el desarrollo independiente de algunos proveedores de navegadores y un proceso iterativo nos han dejado varias versiones diferentes de flexbox a las que todos deben atenderse.
Afortunadamente, con la adición de algunos prefijos de navegador para navegadores heredados, ahora podemos confiar en él. De acuerdo a caniuse.com , de los actuales navegadores mainstream solo IE9 nos presentará un problema.
Afortunadamente, como todo CSS, si flexbox falla, falla silenciosamente. Lo que significa que IE9 simplemente lo ignorará.
Gracias a la asombrosa falta de cooperación entre varias ramas de comités y corporaciones, la implementación de Flexbox casi ha rivalizado con el caos de principios de los '00 cuando cada navegador implementó cada propiedad de forma única e incorrecta al mismo tiempo. Dando a todos el beneficio de la duda, las tres implementaciones de flexbox fueron simplemente un enfoque iterativo que resultó en la solución común más útil.
Hay tres versiones de la sintaxis de Flexbox de las que debe tener conocimiento: antiguas, intermedias y nuevas. Los diferentes navegadores admiten diferentes sintaxis, IE10, por ejemplo, admite la sintaxis intermedia.
Al igual que los prefijos de navegador, escribimos la sintaxis de Flexbox de la más antigua a la más nueva, de modo que la sintaxis compatible más reciente anule las sintaxis antiguas.
Por ejemplo, escribimos display: flex así:
display:-webkit-box; /*old prefixed for webkit*/display:-moz-box; /*old prefixed for mozilla*/display:-ms-flexbox; /*inbetween prefixed for ie*/display:-webkit-flex; /*new prefixed for webkit*/display:flex; /*new*/
En aras de la claridad, no voy a profundizar en las sintaxis más antiguas ni a debatir los méritos de los preprocesadores, los postprocesadores y los diferentes scripts de conversión. En todos mis ejemplos, voy a usar la sintaxis correcta y nueva.
Cuando se trata del código de producción, uso una serie de mixins Sass para extender el soporte de flexbox a los navegadores más antiguos.
Hay un excelente Sass mixin aquí , que puede usar para evitar la hinchazón del código o extraer la sintaxis heredada.
El secreto de flexbox es que no es una caja en absoluto. Hasta ahora, todos los diseños en la Web usaban un sistema cartesiano de xey para trazar puntos. Flexbox, por el contrario, es un vector.
Suena genial, ¿verdad? Flexbox es un vector, lo que significa que definimos una longitud y definimos un ángulo. Podemos cambiar el ángulo, sin afectar la longitud; y podemos alterar la longitud, sin afectar el ángulo.
Este nuevo enfoque significa que parte de la terminología de flexbox es inicialmente compleja. Por ejemplo, cuando alineamos los artículos a la parte superior de un contenedor flexible, utilizamos inicio flexible, no superior, porque si cambiamos la orientación, se seguirá aplicando el inicio flexible , pero no lo hará la parte superior .
Una vez que comprenda este enfoque, gran parte de flexbox se desmitifica.
La sintaxis de Flexbox se divide en dos grupos: las propiedades que controlan el contenedor y las propiedades que controlan los descendientes directos del contenedor. El primero es el más útil, así que comencemos allí.
Digamos que queremos espaciar los elementos dentro de un bloque. Queremos espaciar de manera uniforme. Usar flexbox es realmente fácil de hacer. Lo primero que necesitamos es un margen de beneficio para probar esto:
Flexbox Layout
Es un página HTML simple , con un div de la casa , que contiene cinco divs del sitio que tienen una clase que identifica su función, la cocina, el servicio, el salón, y el dormitorio.
Lo que vamos a hacer es configurar la casa para que sea un contenedor de caja flexible. Todas las propiedades de flexbox que establecemos en house se aplicarán a sus hijos (the room s).
Para diseñar las habitaciones , primero debemos declarar house como un contenedor de flexbox, y luego decirle cómo queremos que se arreglen los elementos secundarios.
Para declarar la casa como un contenedor de flexbox, usamos el siguiente código:
.house {background:#FF5651;display:flex;}
Y eso es. Creamos una caja flexible. Todo lo que tenemos que hacer ahora es decirle a flexbox cómo diseñar la habitación . Podemos hacer eso usando la propiedad justify-content .
justify-content tiene cinco valores posibles: center, flex-start, flex-end, space-around y space-between. Estos centran los elementos, los alinean al inicio (que es superior o izquierdo, como veremos más adelante), el extremo (que es el inferior o el derecho), los espacian con el mismo espacio alrededor de cada elemento, o con espacio igual entre cada elemento, respectivamente.
Usaremos espacio alrededor:
.house {background:#FF5651;display:flex;justify-content: space-around;}
Aquí hay una demostración . ¿Observe cómo hay el doble de espacio entre los elementos que hay en los dos bordes externos? Eso es porque cada elemento tiene el mismo espacio a la izquierda y a la derecha. Si hubiéramos usado espacio-between en su lugar no habría espacio en los bordes.
No estoy seguro de ti, pero el baño de mi casa es un poco más pequeño que el salón, y aunque tengo una cocina pequeña, me encantaría una más grande. Así que hagamos algunas adiciones a nuestro código para reflejar eso:
.kitchen {width:300px;height:300px;}.washroom {width:45px;height:60px;}
Como puedes ver en este ejemplo , nuestras habitaciones están espaciadas uniformemente Aunque hemos cambiado el tamaño. Flexbox es brillante en la organización de contenido.
Como mencionamos anteriormente, una de las razones por las que Flexbox funciona tan bien para los diseñadores es que se describe como un vector. En la actualidad, flexbox solo admite cuatro ángulos: 0, 90, 180 y 270 grados. Entonces, es mucho más simple pensar en ellos como un eje.
Para cambiar el eje, utilizamos la propiedad flex-direction , que tiene cuatro valores posibles: row (el valor predeterminado, como se puede ver en los ejemplos anteriores, nuestras habitaciones se presentan de izquierda a derecha), row-reverse, column y columna inversa.
Si cambiamos la dirección de flexión a columna, verás en esta demo que las habitaciones ahora están dispuestas verticalmente, de arriba abajo:
.house {background:#FF5651;display:flex;justify-content: space-around;flex-direction:column;}
Como estoy seguro de que puede adivinar, la fila invertida y la columna inversa invierten el orden de los elementos en su contenedor flexible.
Notará en el último ejemplo que mientras la casa se extiende a lo largo de la ventana gráfica, se extiende hasta la altura completa, incluso cuando está configurada en dirección flex: columna.
Para jugar muy bien con el sistema de coordenadas cartesianas de CSS, el contenedor de flexbox se trata como un elemento de nivel de bloque.
Al igual que en la pantalla: el bloque tiene una pantalla complementaria : bloque en línea, por lo tanto , para mostrar: flex tiene pantalla: inline-flex.
inline-flex es actualmente más útil si está colocando elementos de flexbox en un diseño existente y lo necesita para jugar bien con flotantes y elementos posicionados.
Como hemos visto, a flexbox no le importa si se coloca horizontal o verticalmente, cualquiera que sea la dirección que elija se considera el eje principal de flexbox.
Pero flexbox también nos permite controlar la posición a lo largo del eje secundario opuesto.
La posición en el eje secundario está controlada por la propiedad align-items ; tiene cinco valores posibles: línea base, centro, extremo flexible, inicio flexible y estiramiento.
la línea de base normalmente será la opción más útil. Asegura que las líneas de base del texto se alineen. Para probar esto, debemos hacer algunas modificaciones a nuestro archivo HTML:
Flexbox Layout KitchenWashroomLoungeBedroomBedroom
Verás que agregué texto e importé, luego apliqué una fuente de Google. También cambié el tamaño de letra en la cocina y el baño, por lo que hay una clara distinción.
Cuando establecemos la propiedad align-items en la línea base , verá en esta demo que la línea base del texto coincide.
.house {background:#FF5651;display:flex;justify-content:space-around;align-items:baseline;}
Align-Items: el centro central se alinea, ya sea verticalmente (si flex-direction: row, o flex-direction: row-reverse ) u horizontalmente (si flex-direction: column, o flex-direction: column-reverse ). Aquí hay una demostración.
alinear elementos: flex-start se alinea con la parte superior y alinear elementos: flex-end se alinea con la parte inferior (si flex-direction: row, o flex-direction: row-reverse ), o hacia la izquierda y derecha (si flex-direction: columna, o flex-direction: column-reverse ). Aquí hay una demostración.
estirar, es otra opción muy útil. stretch ajustará el tamaño de los elementos, de modo que cada uno tenga la misma altura (crecerán, no se encogerán). Aquí hay una demostración.
En nuestros otros ejemplos, hemos establecido explícitamente la altura de los elementos, lo cual es suficiente para anular la flexbox, por lo que para ver elementos de alineación: estirar el trabajo correctamente, deberá eliminar la altura de todas las clases, excepto una.
Hasta ahora, hemos utilizado flexbox para diseñar elementos para que cambien de tamaño a lo largo del espacio, pero ¿qué sucede cuando el contenido de los elementos es demasiado grande para caber en una línea?
Para hacer una demostración de esto, voy a aumentar el tamaño de mis habitaciones:
Flexbox Layout KitchenWashroomLoungeBedroomBedroom
Aquí está como se ve ahora
Si reduce la ventana de su navegador, verá que el contenido se corta, ya que no hay espacio para ello. Afortunadamente Flexbox define una propiedad flex-wrap para esta eventualidad, que tiene tres valores posibles: no-wrap (por defecto), wrap y wrap-reverse.
wrap hace que cualquier elemento que se extienda más allá del contenedor se enrolle en una línea posterior, al igual que una línea de texto.
.house {background:#FF5651;display:flex;justify-content:space-around;align-items:baseline;flex-wrap:wrap;}
Si aplastas tu navegador verás en esta demo los artículos ahora se envuelven en nuevas líneas. Observe cómo todavía se aplica la propiedad alinear elementos: línea base . El verdadero poder de Flexbox es combinar sus propiedades.
Un concepto importante, que cubriré más adelante, es que flex-wrap: wrap-reverse no invierte el orden de los elementos, hace que cualquier elemento que se extienda más allá del contenedor se enrede en una línea anterior, como se ve en esta demo .
Al igual que muchas propiedades de CSS, algunas propiedades de flexbox tienen versiones abreviadas que los fabricantes de exploradores implementan de forma más consistente.
La propiedad flex-flow es una abreviatura de las propiedades flex-direction y flex-wrap . Entonces, en lugar de escribir:
flex-direction:row-reverse;flex-wrap:wrap;
Podemos usar la taquigrafía:
flex-flow:row-reverse wrap;
Arriba, utilizamos la propiedad de alinear elementos para alinear los elementos con la línea de base, la posición y los elementos elásticos. Como puede ver en el último ejemplo, eso todavía está ocurriendo, pero ocurre línea por línea.
Cuando nuestros artículos se han envuelto, tenemos la opción de establecer cómo se distribuirán en el eje secundario si el contenedor es más grande que el requerido.
Si establecemos la altura mínima de nuestra casa en 1200 px, nuestro diseño Se ve como esto .
.house {background:#FF5651;min-height:1200px;display:flex;justify-content:space-around;flex-wrap:wrap;}
Ahora podemos usar la propiedad align-content para diseñar los elementos en todo el eje secundario.
La propiedad de contenido de alineación tiene seis configuraciones: centro, extremo flexible, inicio flexible, espacio alrededor, espacio intermedio y estiramiento. Estos valores ofrecen los mismos resultados que en cualquier otra parte: centrado, alineación en un extremo, espaciado uniforme o estiramiento.
Aquí hay una demostración con la propiedad puesta a espacio-alrededor.
Hasta ahora, todas las propiedades que hemos analizado se han establecido en el elemento contenedor. Con el fin de ajustar los elementos, flexbox también nos proporciona una serie de propiedades que se pueden configurar en elementos individuales.
Para aclarar esto, eliminemos algunos de nuestros códigos:
Flexbox Layout KitchenWashroomLoungeMaster BedroomBedroom
Aquí está como luce.
La primera propiedad del elemento FlexBox es la propiedad flex confusamente llamada. flex es un valor de la propiedad de visualización en el contenedor, pero también es una propiedad en sí misma.
La propiedad flex es una abreviatura de las propiedades flex-grow, flex-shrink y flex-basis . El papel de estas propiedades es estirar o aplastar el tamaño del contenido para que ocupe todo el espacio.
La propiedad flex-grow les dice a los artículos que pueden agrandar, si es necesario, para que los artículos llenen por completo el ancho (para flex-direction: row ) y la altura (para flex-direction: column ).
La propiedad flex-grow toma una proporción. Entonces, si establecemos la propiedad flex-grow en 1, todos nuestros artículos serán del mismo tamaño que puedes ver aquí .
.room {background:#00AAF2;height:90px;flex-grow:1;}
Además de tomar un tamaño igual, también podemos establecer diferentes proporciones. Todavía quiero que mi cocina sea más grande que mi baño, así que vamos a arreglar eso en esta demo .
.kitchen {height:300px;flex-grow:2;}
flex-shrink funciona exactamente igual que flex-grow, excepto que encoge el elemento si es necesario, en lugar de expandirlo.
Si cambias el tamaño del navegador verás que en diferentes tamaños, mi cocina no es exactamente el doble del ancho de las otras habitaciones . Eso se debe a la propiedad de base flexible .
Flex-Base determina cómo se calculan las propiedades de crecimiento flexible y contracción flexible . Tiene 2 valores: automático (predeterminado) y 0.
Si se establece en 0, se tiene en cuenta todo el artículo. Si se establece en automático , se cambia el tamaño del relleno del contenido del elemento. En otras palabras, 0 ignora el tamaño del contenido del elemento cuando calcula y lo toma en cuenta automáticamente . Hay una Diagrama práctico proporcionado por el W3C que explica esto.
Aquí hay una demostración de lo que sucede cuando establezco flex-basis: 0 en el ejemplo anterior.
flex-basis: 0 es particularmente útil si desea espaciar los elementos de manera uniforme, independientemente de su contenido.
Como se indicó anteriormente, la propiedad flex es una forma abreviada de estas propiedades, y encontrará que es la forma más confiable de establecer estos valores.
El orden de los valores es flex-grow, flex-shrink, flex-basis. Por lo tanto, para establecer un valor de crecimiento de 2, un valor de contracción de 1 y una base de 0, usaría:
.room {background:#00AAF2;height:90px;flex: 2 1 0;}
Una de las mejores características de flexbox es su capacidad para cambiar el orden de los elementos, sin afectar el marcado; esto es particularmente útil para la accesibilidad, ya que nos permite codificar el marcado de forma adecuada y luego mostrarlo de manera óptima.
Para hacer esto usamos la propiedad de pedido del artículo.
Mirando nuestro ejemplo, el baño está justo al lado de la cocina. Prefiero que esté al lado de las habitaciones, así que puedo saltar directamente a la ducha de la mañana, así que vamos a moverlo. Actualmente es el segundo elemento, queremos que sea el tercero. Así que establecemos su propiedad de pedido en consecuencia en esta demo .
.washroom {height:60px;order:2;}
¿Ves cómo saltó hasta el final de la fila? Está al lado de las habitaciones, pero no como queríamos. Este es un gran problema en flexbox, porque muchos desarrolladores (incluido yo mismo) inicialmente esperan que el orden opere como una matriz.
el orden realmente funciona como el índice z de CSS , lo que significa que si no establece explícitamente un pedido para un artículo, se supone que es menor en el orden que un elemento para el que se ha establecido explícitamente un valor.
Queremos que el baño se cambie con el salón, por lo que en esta demo los únicos otros artículos que necesitan un pedido son los dormitorios .
.washroom {height:60px;order:2;}.bedroom {order:3;}
Observe cómo ambas habitaciones comparten el mismo número de orden? En casos como esos, el navegador recurrirá a la orden DOM.
La propiedad del elemento final es Align-Self. Se usa para cambiar la alineación del elemento en el eje secundario. Align-Items se usa para alinear todos los elementos, y esta propiedad le da la opción de cancelar la configuración de esa manta.
Toma los mismos cinco valores que la propiedad equivalente en el contenedor: línea base, centro, extremo flexible, inicio flexible y estiramiento.
Aquí hay una demostración del baño re-alineado.
.washroom {height:60px;order:2;align-self:flex-end;}
Flexbox es una poderosa opción para diseñar contenido. Aunque no está diseñado para diseñar páginas enteras, su compatibilidad superior con el Diseño de cuadrícula lo convierte en una excelente opción, especialmente para sitios web que se basan primero en dispositivos móviles.
Para demostrar, vamos a armar una página simple que use algunas de las técnicas descritas anteriormente.
Primero está nuestro marcado, y algunos estilos básicos para la página.
Flexbox Demo - A
- B
- C
- D
- E
- F
- G
Como puedes ver , Tengo un div con la página de identificación . Dentro de la página tengo una lista desordenada de noticias. Después de las noticias, tengo el encabezado, que está debajo del contenido de noticias para el beneficio de la accesibilidad. Finalmente, tengo un pie de página.
Lo primero que quiero hacer es mover el encabezado hasta la parte superior de la página. Para hacer eso, configuraremos la página para que sea un contenedor de flexbox. Luego, estableceremos la dirección en la columna. Luego asigne un orden a cada uno de los elementos secundarios de la página .
#page {display:flex;}#page {display:flex;flex-flow:column;}#header {order:1;}#news {order:2;}#footer {order:3;}
El siguiente paso es diseñar el encabezado. Los elementos secundarios dentro de los contenedores de flexbox pueden ser contenedores de flexbox por derecho propio, por lo que podemos usar flexbox para espaciar uniformemente los elementos de encabezado .
Establezcamos que el encabezado sea un contenedor de flexbox, luego espaciemos el contenido de manera uniforme, sin relleno adicional a los lados, y finalmente asegurémonos de que los elementos del menú estén en la misma línea base que el logotipo.
#header {order:1;display:flex;justify-content:space-between;align-items:baseline;}
Nuestras noticias serán marcadores de posición para las historias destacadas, por lo que deben ser de un tamaño considerable para dejar espacio para el texto y una imagen o video. Entonces, necesitamos que se envuelvan.
Vamos a configurar el div de noticias para que sea un contenedor de caja flexible. A continuación, demos al newsItem unas dimensiones mínimas y un poco de color para que podamos verlas con claridad.
#news {order:2;display:flex;}.newsItem {min-width:300px;min-height:250px;background:#79797B;border:1px solid #706667;}
Ahora tenemos que configurar el contenedor de noticias para que se ajuste, y el newsItem se expanda para llenar el espacio disponible.
#news {order:2;display:flex;flex-flow:row wrap;}
El desafío que tenemos ahora, es que cuando los artículos de noticias no están distribuidos uniformemente, el artículo más grande (G) está en la parte inferior. En la mayoría de los sitios, queremos dar la mayor cantidad de espacio al contenido más elevado. Podemos solucionar esto estableciendo el wrap para wrap-reverse.
#news {order:2;display:flex;flex-flow:row wrap-reverse;}
Eso reordena los artículos, pero leyendo desde arriba a la izquierda, ahora están fuera de servicio. Por lo tanto, necesitamos invertir el orden, estableciendo la dirección en row-reverse.
#news {order:2;display:flex;flex-flow:row-reverse wrap-reverse;}
Eso coloca los artículos en orden consecutivo, leyendo de izquierda a derecha, de arriba a abajo; con los artículos más grandes siempre en la parte superior. Pero no quiero tener que alterar el orden de las historias en mi marcado para forzar que el ítem A venga antes que el ítem B. Entonces, lo último que tengo que hacer es cambiar el orden de los ítems.
.newsItem:nth-of-type(7) {order:1;}.newsItem:nth-of-type(6) {order:2;}.newsItem:nth-of-type(5) {order:3;}.newsItem:nth-of-type(4) {order:4;}.newsItem:nth-of-type(3) {order:5;}.newsItem:nth-of-type(2) {order:6;}.newsItem:nth-of-type(1) {order:7;}
El último elemento a diseñar es el pie de página. Queremos diseñarlo, al igual que el encabezado, pero debido a que el pie de página solo tiene tres elementos secundarios (en comparación con los cuatro del encabezado ), vamos a establecer que el párrafo sea el doble de ancho que el logotipo, y la lista .
#footer {order:3;display:flex;align-items:baseline;flex-direction:row;}#footer > * {flex:1;}#footer > p {flex:2;padding-right:2em;}
Eso funciona muy bien en los tamaños de escritorio, pero reduce el tamaño de tu navegador y verás que está demasiado apretado en dispositivos pequeños. Así que cambiemos el código para que se distribuya como columnas debajo de 600px, y revierte a una fila por encima de 600px.
#footer {order:3;display:flex;align-items:baseline;flex-direction:column;padding:2em 0;}#footer > * {flex:1;}#footer > p {flex:2;}@media only screen and (min-width:600px) {#footer {flex-direction:row;padding:0;}#footer > p {margin-right:2em;}}
Y ahí lo tienes. Un enfoque moderno para diseñar contenido en una página web, que es ampliamente compatible y fácil de implementar.
El poder de flexbox es que sus propiedades se pueden combinar para brindarnos un control preciso sobre nuestros diseños, con la sintaxis más simple posible.