Una guía completa de Flexbox - Trucos CSS

Fondo

El Flexbox Layoutmódulo (Caja flexible) (una recomendación candidata del W3C a octubre de 2017) tiene como objetivo proporcionar una forma más eficiente de diseñar, alinear y distribuir el espacio entre los elementos de un contenedor, incluso cuando su tamaño es desconocido y / o dinámico (por lo tanto, el palabra "flex").

La idea principal detrás del diseño flexible es darle al contenedor la capacidad de alterar el ancho / alto (y el orden) de sus elementos para llenar mejor el espacio disponible (principalmente para adaptarse a todo tipo de dispositivos de visualización y tamaños de pantalla). Un contenedor flexible expande los artículos para llenar el espacio libre disponible o los encoge para evitar que se desborden.

Lo más importante es que el diseño de flexbox es independiente de la dirección a diferencia de los diseños regulares (bloque que tiene una base vertical y en línea que tiene una base horizontal). Si bien funcionan bien para las páginas, carecen de flexibilidad (sin juego de palabras) para admitir aplicaciones grandes o complejas (especialmente cuando se trata de cambiar la orientación, cambiar el tamaño, estirar, encoger, etc.).

Nota: El diseño de caja flexible es más apropiado para los componentes de una aplicación y diseños de pequeña escala, mientras que el diseño de cuadrícula está diseñado para diseños de mayor escala.

Conceptos básicos y terminología

Dado que flexbox es un módulo completo y no una sola propiedad, involucra muchas cosas, incluido todo su conjunto de propiedades. Algunos de ellos están destinados a establecerse en el contenedor (elemento padre, conocido como "contenedor flexible") mientras que los otros están destinados a establecerse en los hijos (dichos "elementos flexibles").

Si el diseño "regular" se basa en direcciones de flujo en línea y en bloque, el diseño flexible se basa en "direcciones de flujo flexible". Eche un vistazo a esta figura de la especificación, que explica la idea principal detrás del diseño flexible.

Los elementos se distribuirán siguiendo el main axis(desde main-starta main-end) o el eje transversal (desde cross-starthasta cross-end).

  • eje principal: el eje principal de un contenedor flexible es el eje principal a lo largo del cual se colocan los elementos flexibles. Cuidado, no es necesariamente horizontal; depende de la flex-directionpropiedad (ver más abajo).
  • inicio principal | main-end : los elementos flexibles se colocan dentro del contenedor comenzando desde el inicio principal hasta el final principal.
  • tamaño principal : el ancho o alto de un elemento flexible, cualquiera que sea la dimensión principal, es el tamaño principal del elemento. La propiedad de tamaño principal del elemento flexible es la propiedad 'ancho' o 'alto', cualquiera que esté en la dimensión principal.
  • eje transversal : el eje perpendicular al eje principal se denomina eje transversal. Su dirección depende de la dirección del eje principal.
  • inicio cruzado | Extremo transversal : las líneas flexibles se llenan con artículos y se colocan en el contenedor comenzando en el lado de inicio cruzado del contenedor flexible y yendo hacia el lado del extremo transversal.
  • tamaño cruzado : el ancho o alto de un artículo flexible, cualquiera que esté en la dimensión cruzada, es el tamaño cruzado del artículo. La propiedad de tamaño cruzado es cualquiera de 'ancho' o 'alto' que esté en la dimensión cruzada.

¡Consigue el cartel!

¿Consulta mucho esta guía? Fija una copia en la pared de la oficina.

Comprar cartel

Propiedades para el padre
(contenedor flexible)

mostrar

Esto define un contenedor flexible; en línea o en bloque según el valor dado. Permite un contexto flexible para todos sus hijos directos.

.container ( display: flex; /* or inline-flex */ )

Tenga en cuenta que las columnas CSS no tienen ningún efecto en un contenedor flexible.

dirección flexible

Esto establece el eje principal, definiendo así la dirección en que se colocan los elementos flexibles en el contenedor flexible. Flexbox es (aparte de la envoltura opcional) un concepto de diseño de una sola dirección. Piense en los elementos flexibles como distribuidos principalmente en filas horizontales o columnas verticales.

.container ( flex-direction: row | row-reverse | column | column-reverse; )
  • row(predeterminado): de izquierda a derecha en ltr; de derecha a izquierda enrtl
  • row-reverse: de derecha a izquierda adentro ltr; de izquierda a derecha enrtl
  • column: igual que rowpero de arriba a abajo
  • column-reverse: igual que row-reversepero de abajo hacia arriba

envoltura flexible

De forma predeterminada, todos los elementos flexibles intentarán encajar en una línea. Puede cambiar eso y permitir que los elementos se ajusten según sea necesario con esta propiedad.

.container ( flex-wrap: nowrap | wrap | wrap-reverse; )
  • nowrap (predeterminado): todos los elementos flexibles estarán en una línea
  • wrap: los elementos flexibles se envolverán en varias líneas, de arriba a abajo.
  • wrap-reverse: los elementos flexibles se envolverán en varias líneas de abajo hacia arriba.

Hay algunas demostraciones visuales de flex-wrapaquí.

flujo flexible

Esta es una abreviatura de las propiedades flex-directiony flex-wrap, que juntas definen los ejes principal y transversal del contenedor flexible. El valor predeterminado es row nowrap.

.container ( flex-flow: column wrap; )

justificar el contenido

Esto define la alineación a lo largo del eje principal. Ayuda a distribuir el espacio libre adicional que queda cuando todos los elementos flexibles de una línea son inflexibles o son flexibles pero han alcanzado su tamaño máximo. También ejerce cierto control sobre la alineación de los elementos cuando desbordan la línea.

.container ( justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right… + safe | unsafe; )
  • flex-start (predeterminado): los elementos se empaquetan hacia el inicio de la dirección flexible.
  • flex-end: los artículos se empaquetan hacia el final de la dirección de flexión.
  • start: los artículos se empaquetan hacia el inicio de la writing-modedirección.
  • end: los artículos se empaquetan hacia el final de la writing-modedirección.
  • left: los artículos se empaquetan hacia el borde izquierdo del contenedor, a menos que eso no tenga sentido con flex-direction, entonces se comporta como start.
  • right: los artículos se empaquetan hacia el borde derecho del contenedor, a menos que eso no tenga sentido con el flex-direction, entonces se comporta como end.
  • center: los elementos están centrados a lo largo de la línea
  • space-between: los artículos se distribuyen uniformemente en la línea; el primer elemento está en la línea de inicio, el último elemento en la línea final
  • space-around: los elementos se distribuyen uniformemente en la línea con el mismo espacio alrededor. Tenga en cuenta que visualmente los espacios no son iguales, ya que todos los elementos tienen el mismo espacio en ambos lados. El primer elemento tendrá una unidad de espacio contra el borde del contenedor, pero dos unidades de espacio entre el siguiente elemento porque el siguiente elemento tiene su propio espacio que se aplica.
  • space-evenly: los elementos se distribuyen de modo que el espacio entre dos elementos (y el espacio hasta los bordes) sea igual.

Tenga en cuenta que la compatibilidad del navegador con estos valores está matizada. Por ejemplo, space-betweennunca recibió soporte de algunas versiones de Edge, y el inicio / final / izquierda / derecha aún no está en Chrome. MDN tiene gráficos detallados. Los valores son más seguros flex-start, flex-endy center.

También hay dos palabras clave adicionales que puede emparejar con estos valores: safey unsafe. El uso safegarantiza que, independientemente de cómo realice este tipo de posicionamiento, no podrá empujar un elemento de manera que se muestre fuera de la pantalla (por ejemplo, fuera de la parte superior) de tal manera que el contenido no pueda desplazarse también (lo que se denomina "pérdida de datos") .

alinear-elementos

Esto define el comportamiento predeterminado de cómo se distribuyen los elementos flexibles a lo largo del eje transversal en la línea actual. Piense en ello como la justify-contentversión para el eje transversal (perpendicular al eje principal).

.container ( align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end +… safe | unsafe; )
  • stretch (predeterminado): estirar para llenar el contenedor (aún respetando el ancho mínimo / ancho máximo)
  • flex-start/ start/ self-start: los elementos se colocan al inicio del eje transversal. La diferencia entre estos es sutil y se trata de respetar las flex-directionreglas o las writing-modereglas.
  • flex-end/ end/ self-end: Elementos se colocan en el extremo del eje transversal. Nuevamente, la diferencia es sutil y se trata de respetar flex-directionreglas versus writing-modereglas.
  • center: los elementos están centrados en el eje transversal
  • baseline: los elementos están alineados, como sus líneas de base se alinean

Las palabras clave safey unsafemodificadoras se pueden usar junto con el resto de estas palabras clave (aunque tenga en cuenta la compatibilidad con el navegador), y tratar de ayudarlo a evitar alinear elementos de modo que el contenido se vuelva inaccesible.

alinear contenido

Esto alinea las líneas de un contenedor flexible dentro cuando hay espacio adicional en el eje transversal, similar a cómo justify-contentalinea elementos individuales dentro del eje principal.

Nota: esta propiedad solo tiene efecto en contenedores flexibles de varias líneas, donde flex-flowse establece en wrapo wrap-reverse). Un contenedor flexible de una sola línea (es decir, donde flex-flowse establece en su valor predeterminado no-wrap) no reflejará align-content.

.container ( align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline +… safe | unsafe; )
  • normal (predeterminado): los elementos se empaquetan en su posición predeterminada como si no se hubiera establecido ningún valor.
  • flex-start/ start: artículos empaquetados al inicio del contenedor. El (más apoyado) flex-starthonra el flex-directionmientras starthonra la writing-modedirección.
  • flex-end/ end: artículos empaquetados hasta el final del contenedor. El (más apoyo) flex-endhonra al flex-directionfinal mientras honra la writing-modedirección.
  • center: elementos centrados en el contenedor
  • space-between: artículos distribuidos uniformemente; la primera línea está al comienzo del contenedor mientras que la última está al final
  • space-around: elementos distribuidos uniformemente con el mismo espacio alrededor de cada línea
  • space-evenly: los elementos se distribuyen uniformemente con el mismo espacio a su alrededor
  • stretch: las líneas se estiran para ocupar el espacio restante

Las palabras clave safey unsafemodificadoras se pueden usar junto con el resto de estas palabras clave (aunque tenga en cuenta la compatibilidad con el navegador), y tratar de ayudarlo a evitar alinear elementos de modo que el contenido se vuelva inaccesible.

Propiedades para los niños
(elementos flexibles)

orden

De forma predeterminada, los elementos flexibles se presentan en el orden de origen. Sin embargo, la orderpropiedad controla el orden en que aparecen en el contenedor flexible.

.item ( order: 5; /* default is 0 */ )

crecimiento flexible

Esto define la capacidad de un artículo flexible para crecer si es necesario. Acepta un valor sin unidades que sirve como proporción. Dicta la cantidad de espacio disponible dentro del contenedor flexible que debe ocupar el artículo.

Si todos los elementos se han flex-growestablecido en 1, el espacio restante en el contenedor se distribuirá por igual a todos los niños. Si uno de los niños tiene un valor de 2, el espacio restante ocuparía el doble de espacio que los demás (o lo intentará, al menos).

.item ( flex-grow: 4; /* default 0 */ )

Los números negativos no son válidos.

flexión-encogimiento

Esto define la capacidad de un artículo flexible de encogerse si es necesario.

.item ( flex-shrink: 3; /* default 1 */ )

Los números negativos no son válidos.

base flexible

This defines the default size of an element before the remaining space is distributed. It can be a length (e.g. 20%, 5rem, etc.) or a keyword. The auto keyword means “look at my width or height property” (which was temporarily done by the main-size keyword until deprecated). The content keyword means “size it based on the item’s content” - this keyword isn’t well supported yet, so it’s hard to test and harder to know what its brethren max-content, min-content, and fit-content do.

.item ( flex-basis: | auto; /* default auto */ )

If set to 0, the extra space around content isn’t factored in. If set to auto, the extra space is distributed based on its flex-grow value. See this graphic.

flex

This is the shorthand for flex-grow, flex-shrink and flex-basis combined. The second and third parameters (flex-shrink and flex-basis) are optional. The default is 0 1 auto, but if you set it with a single number value, it’s like 1 0.

.item ( flex: none | ( ? || ) )

It is recommended that you use this shorthand property rather than set the individual properties. The shorthand sets the other values intelligently.

align-self

This allows the default alignment (or the one specified by align-items) to be overridden for individual flex items.

Please see the align-items explanation to understand the available values.

.item ( align-self: auto | flex-start | flex-end | center | baseline | stretch; )

Note that float, clear and vertical-align have no effect on a flex item.

Examples

Let’s start with a very very simple example, solving an almost daily problem: perfect centering. It couldn’t be any simpler if you use flexbox.

.parent ( display: flex; height: 300px; /* Or whatever */ ) .child ( width: 100px; /* Or whatever */ height: 100px; /* Or whatever */ margin: auto; /* Magic! */ )

This relies on the fact a margin set to auto in a flex container absorb extra space. So setting a vertical margin of auto will make the item perfectly centered in both axes.

Now let’s use some more properties. Consider a list of 6 items, all with fixed dimensions, but can be auto-sized. We want them to be evenly distributed on the horizontal axis so that when we resize the browser, everything scales nicely, and without media queries.

.flex-container ( /* We first create a flex layout context */ display: flex; /* Then we define the flow direction and if we allow the items to wrap * Remember this is the same as: * flex-direction: row; * flex-wrap: wrap; */ flex-flow: row wrap; /* Then we define how is distributed the remaining space */ justify-content: space-around; )

Done. Everything else is just some styling concern. Below is a pen featuring this example. Be sure to go to CodePen and try resizing your windows to see what happens.

Let’s try something else. Imagine we have a right-aligned navigation element on the very top of our website, but we want it to be centered on medium-sized screens and single-columned on small devices. Easy enough.

/* Large */ .navigation ( display: flex; flex-flow: row wrap; /* This aligns items to the end line on main-axis */ justify-content: flex-end; ) /* Medium screens */ @media all and (max-width: 800px) ( .navigation ( /* When on medium sized screens, we center it by evenly distributing empty space around items */ justify-content: space-around; ) ) /* Small screens */ @media all and (max-width: 500px) ( .navigation ( /* On small screens, we are no longer using row direction but column */ flex-direction: column; ) )

Let’s try something even better by playing with flex items flexibility! What about a mobile-first 3-columns layout with full-width header and footer. And independent from source order.

.wrapper ( display: flex; flex-flow: row wrap; ) /* We tell all items to be 100% width, via flex-basis */ .wrapper> * ( flex: 1 100%; ) /* We rely on source order for mobile-first approach * in this case: * 1. header * 2. article * 3. aside 1 * 4. aside 2 * 5. footer */ /* Medium screens */ @media all and (min-width: 600px) ( /* We tell both sidebars to share a row */ .aside ( flex: 1 auto; ) ) /* Large screens */ @media all and (min-width: 800px) ( /* We invert order of first sidebar and main * And tell the main element to take twice as much width as the other two sidebars */ .main ( flex: 2 0px; ) .aside-1 ( order: 1; ) .main ( order: 2; ) .aside-2 ( order: 3; ) .footer ( order: 4; ) )

Prefixing Flexbox

Flexbox requires some vendor prefixing to support the most browsers possible. It doesn’t just include prepending properties with the vendor prefix, but there are actually entirely different property and value names. This is because the Flexbox spec has changed over time, creating an “old”, “tweener”, and “new” versions.

Perhaps the best way to handle this is to write in the new (and final) syntax and run your CSS through Autoprefixer, which handles the fallbacks very well.

Alternatively, here’s a Sass @mixin to help with some of the prefixing, which also gives you an idea of what kind of things need to be done:

@mixin flexbox() ( display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; ) @mixin flex($values) ( -webkit-box-flex: $values; -moz-box-flex: $values; -webkit-flex: $values; -ms-flex: $values; flex: $values; ) @mixin order($val) ( -webkit-box-ordinal-group: $val; -moz-box-ordinal-group: $val; -ms-flex-order: $val; -webkit-order: $val; order: $val; ) .wrapper ( @include flexbox(); ) .item ( @include flex(1 200px); @include order(2); )

Related Properties

  • A Complete Guide to Grid
  • Almanac entries on Grid properties, like grid-row / grid-column

Other Resources

  • Flexbox in the CSS specifications
  • Flexbox at MDN
  • Flexbox at Opera
  • Diving into Flexbox by Bocoup
  • Mixing syntaxes for best browser support on CSS-Tricks
  • Flexbox by Raphael Goetter (FR)
  • Flexplorer by Bennett Feely

Bugs

Flexbox is certainly not without its bugs. The best collection of them I’ve seen is Philip Walton and Greg Whitworth’s Flexbugs. It’s an open-source place to track all of them, so I think it’s best to just link to that.

Soporte del navegador

Desglosado por "versión" de flexbox:

  • (nuevo) significa la sintaxis reciente de la especificación (p display: flex;. ej. )
  • (tweener) significa una sintaxis no oficial extraña de 2011 (p display: flexbox;. ej. )
  • (antiguo) significa la sintaxis antigua de 2009 (p display: box;. ej. )
Cromo Safari Firefox Ópera ES DECIR Borde Androide iOS
20- (antiguo)
21+ (nuevo)
3.1+ (antiguo)
6.1+ (nuevo)
2-21 (antiguo)
22+ (nuevo)
12.1+ (nuevo) 10 (tweener)
11+ (nuevo)
17+ (nuevo) 2.1+ (antiguo)
4.4+ (nuevo)
3.2+ (antiguo)
7.1+ (nuevo)

El navegador Blackberry 10+ admite la nueva sintaxis.

Articulos interesantes...