Fondo
El Flexbox Layout
mó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-start
a main-end
) o el eje transversal (desde cross-start
hasta 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-direction
propiedad (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 cartelPropiedades 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 enltr
; de derecha a izquierda enrtl
row-reverse
: de derecha a izquierda adentroltr
; de izquierda a derecha enrtl
column
: igual querow
pero de arriba a abajocolumn-reverse
: igual querow-reverse
pero 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íneawrap
: 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-wrap
aquí.
flujo flexible
Esta es una abreviatura de las propiedades flex-direction
y 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 lawriting-mode
dirección.end
: los artículos se empaquetan hacia el final de lawriting-mode
dirección.left
: los artículos se empaquetan hacia el borde izquierdo del contenedor, a menos que eso no tenga sentido conflex-direction
, entonces se comporta comostart
.right
: los artículos se empaquetan hacia el borde derecho del contenedor, a menos que eso no tenga sentido con elflex-direction
, entonces se comporta comoend
.center
: los elementos están centrados a lo largo de la líneaspace-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 finalspace-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-between
nunca 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-end
y center
.
También hay dos palabras clave adicionales que puede emparejar con estos valores: safe
y unsafe
. El uso safe
garantiza 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-content
versió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 lasflex-direction
reglas o laswriting-mode
reglas.flex-end
/end
/self-end
: Elementos se colocan en el extremo del eje transversal. Nuevamente, la diferencia es sutil y se trata de respetarflex-direction
reglas versuswriting-mode
reglas.center
: los elementos están centrados en el eje transversalbaseline
: los elementos están alineados, como sus líneas de base se alinean
Las palabras clave safe
y unsafe
modificadoras 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-content
alinea elementos individuales dentro del eje principal.
Nota: esta propiedad solo tiene efecto en contenedores flexibles de varias líneas, donde flex-flow
se establece en wrap
o wrap-reverse
). Un contenedor flexible de una sola línea (es decir, donde flex-flow
se 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-start
honra elflex-direction
mientrasstart
honra lawriting-mode
dirección.flex-end
/end
: artículos empaquetados hasta el final del contenedor. El (más apoyo)flex-end
honra alflex-direction
final mientras honra lawriting-mode
dirección.center
: elementos centrados en el contenedorspace-between
: artículos distribuidos uniformemente; la primera línea está al comienzo del contenedor mientras que la última está al finalspace-around
: elementos distribuidos uniformemente con el mismo espacio alrededor de cada líneaspace-evenly
: los elementos se distribuyen uniformemente con el mismo espacio a su alrededorstretch
: las líneas se estiran para ocupar el espacio restante
Las palabras clave safe
y unsafe
modificadoras 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 order
propiedad 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-grow
establecido 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.