guia content container align css css3 flexbox

css - container - ¿Cómo funciona flex-wrap con align-self, align-items y align-content?



flexbox guia (2)

align-self

En el siguiente código, align-self funciona con flex-wrap: nowrap .

flex-container { display: flex; flex-wrap: nowrap; align-content: flex-start; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; } flex-item:last-child { align-self: flex-end; background-color: crimson; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

Pero cuando el contenedor se cambia a flex-wrap: wrap , la propiedad align-self falla.

flex-container { display: flex; flex-wrap: wrap; align-content: flex-start; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; } flex-item:last-child { align-self: flex-end; background-color: crimson; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

align-items

Del mismo modo, ¿por qué align-items funcionan aquí (ajuste deshabilitado):

flex-container { display: flex; flex-wrap: nowrap; align-items: flex-end; align-content: flex-start; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

... pero no aquí (ajuste habilitado):

flex-container { display: flex; flex-wrap: wrap; align-items: flex-end; align-content: flex-start; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

align-content

Con flex-wrap: nowrap , la propiedad de align-content no centrará verticalmente los elementos flexibles aquí:

flex-container { display: flex; flex-wrap: nowrap; align-content: center; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

Pero entonces, extrañamente, si se habilita el align-content y se align-content , el contenedor crea espacios amplios entre las filas aquí:

flex-container { display: flex; flex-wrap: wrap; /* align-content: center; */ width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

Y align-self funciona de nuevo.

flex-container { display: flex; flex-wrap: wrap; /* align-content: center; */ width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; } flex-item:nth-child(even) { align-self: flex-end; background-color: crimson; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

¿Cómo funciona flex-wrap con align-self , align-items y align-content?


Respuesta corta

Aunque la propiedad de ajuste flex-wrap parece bastante básica (controla si los elementos flexibles pueden ajustarse), en realidad tiene un amplio impacto en todo el diseño de flexbox.

La propiedad flex-wrap determina el tipo de contenedor flexible que usará.

  • flex-wrap: nowrap crea un contenedor flexible de una sola línea
  • flex-wrap: wrap y wrap-reverse crean un contenedor flexible de varias líneas

Las propiedades align-items y align-self funcionan en contenedores de una o varias líneas. Sin embargo, solo pueden tener un efecto cuando hay espacio libre en el eje transversal de la línea flexible.

La propiedad de align-content solo funciona en contenedores de varias líneas. Se ignora en contenedores de una sola línea.

Explicación

La especificación flexbox proporciona cuatro propiedades de palabras clave para alinear elementos flex:

  • align-items
  • align-self
  • align-content
  • justify-content

Para comprender las funciones de estas propiedades, es importante comprender primero la estructura de un contenedor flexible.

Parte 1: Comprender el eje principal y el eje transversal de un contenedor flexible

Los ejes X e Y

Un contenedor flexible funciona en dos direcciones: eje x (horizontal) y eje y (vertical).

Fuente: Wikipedia

Los elementos secundarios de un contenedor flexible, conocidos como "elementos flexibles", se pueden alinear en cualquier dirección.

Esta es la alineación flexible en su nivel más fundamental.

Los ejes principales y cruzados

La superposición de los ejes x e y son, en diseño flexible, los ejes principal y transversal .

Por defecto, el eje principal es horizontal (eje x) y el eje transversal es vertical (eje y). Esa es la configuración inicial, tal como se define en la especificación de flexbox .

Fuente: W3C

Sin embargo, a diferencia de los ejes x e y, que son fijos, los ejes principal y transversal pueden cambiar de dirección.

La propiedad de flex-direction

En la imagen de arriba, el eje principal es horizontal y el eje transversal es vertical. Como se mencionó anteriormente, esa es una configuración inicial de un contenedor flexible.

Sin embargo, estas direcciones se pueden cambiar fácilmente con la propiedad de flex-direction . Esta propiedad controla la dirección del eje principal; determina si los elementos flexibles se alinean vertical u horizontalmente.

De la especificación:

5.1. Dirección de flujo flexible: la propiedad de flex-direction

La propiedad de flex-direction especifica cómo se colocan los elementos flexibles en el contenedor flexible, al establecer la dirección del eje principal del contenedor flexible. Esto determina la dirección en la que se disponen los elementos flexibles.

Hay cuatro valores para la propiedad de flex-direction :

/* main axis is horizontal, cross axis is vertical */ flex-direction: row; /* default */ flex-direction: row-reverse; /* main axis is vertical, cross axis is horizontal */ flex-direction: column; flex-direction: column-reverse;

El eje transversal es siempre perpendicular al eje principal.

Parte 2: líneas flexibles

Dentro del contenedor, los artículos flexibles existen en una línea, conocida como "línea flexible".

Una línea flexible es una fila o columna, dependiendo de flex-direction .

Un contenedor puede tener una o más líneas, dependiendo de flex-wrap .

Contenedor flexible de una línea

flex-wrap: nowrap establece un contenedor flexible de una sola línea, en el que los elementos flexibles se ven obligados a permanecer en una sola línea (incluso si desbordan el contenedor).

La imagen de arriba tiene una línea flexible.

flex-container { display: flex; flex-direction: column; flex-wrap: nowrap; /* <-- allows single-line flex container */ width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; width: 50px; margin: 5px; background-color: lightgreen; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

Contenedor Flex Multi-Line

flex-wrap: wrap o wrap-reverse establece un contenedor flexible de varias líneas, en el que los elementos flexibles pueden crear nuevas líneas.

La imagen de arriba tiene tres líneas flexibles.

flex-container { display: flex; flex-direction: column; flex-wrap: wrap; /* <-- allows multi-line flex container */ width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; width: 50px; margin: 5px; background-color: lightgreen; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

La imagen de arriba tiene tres líneas flexibles.

flex-container { display: flex; flex-direction: row; flex-wrap: wrap; /* <-- allows multi-line flex container */ width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

Parte 3: Propiedades de alineación de palabras clave

Las propiedades se asignan a los ejes principal y cruzado (no X e Y)

Si bien la propiedad de flex-direction controla la dirección en la que se disponen los elementos flexibles, existen cuatro propiedades que controlan la alineación y el posicionamiento. Estos son:

  • align-items
  • align-self
  • align-content
  • justify-content

Cada una de estas propiedades está asignada permanentemente a un eje.

La propiedad justify-content funciona solo en el eje principal.

Las tres propiedades align-* funcionan solo en el eje transversal.

Es un error común suponer que estas propiedades están fijadas a los ejes x e y. Por ejemplo, justify-content siempre es horizontal y align-items siempre es vertical.

Sin embargo, cuando flex-direction se cambia a column , el eje principal se convierte en el eje y, y justify-content funciona verticalmente.

El enfoque de esta publicación es la alineación de ejes cruzados. Para una explicación de la alineación del eje principal y la propiedad justify-content , vea esta publicación:

  • En CSS Flexbox, ¿por qué no hay propiedades "justify-items" y "justify-self"?

Definiciones

La especificación flexbox proporciona tres propiedades de palabras clave para la alineación de ejes cruzados:

  • align-items
  • align-self
  • align-content

align-items / align-self

La propiedad align-items alinea los elementos flexibles a lo largo del eje transversal de la línea flexible. Se aplica a contenedores flexibles.

La propiedad align-self se usa para anular elementos de align-items flexibles individuales. Se aplica a artículos flexibles.

Aquí está la definición de la especificación:

8.3. Alineación de ejes cruzados: las propiedades align-items y align-self

Los elementos flexibles se pueden alinear en el eje transversal de la línea actual del contenedor flexible, similar al justify-content pero en la dirección perpendicular. align-items establece la alineación predeterminada para todos los elementos del contenedor flexible. align-self permite que esta alineación predeterminada se anule para elementos flexibles individuales.

Hay seis valores posibles para align-items / align-self :

  • flex-start
  • flex-end
  • center
  • baseline
  • stretch
  • auto (solo align-self )

(Para obtener una descripción de cada valor, haga clic en el encabezado de definición de especificación anterior).

El valor inicial de align-items de align-items es stretch , lo que significa que los elementos flexibles expandirán la longitud total disponible del eje transversal del contenedor.

El valor inicial de align-self es auto , lo que significa que hereda el valor de align-items .

A continuación se muestra una ilustración del efecto de cada valor en un contenedor de dirección de fila.

fuente: W3C

align-content

Esta propiedad es un poco más compleja que align-items y align-self .

Aquí está la definición de la especificación:

8.4. Empaquetado de líneas flexibles: la propiedad de align-content

La propiedad de align-content alinea las líneas de un contenedor flexible dentro del contenedor flexible cuando hay espacio adicional en el eje transversal, de forma similar a cómo justify-content alinea elementos individuales dentro del eje principal. Tenga en cuenta que esta propiedad no tiene efecto en un contenedor flexible de una sola línea.

A diferencia de align-items y align-self , que mueven elementos flexibles dentro de su línea , align-content mueve líneas flexibles dentro del contenedor .

Existen los seis valores posibles para align-content :

  • flex-start
  • flex-end
  • center
  • space-between
  • space-around
  • stretch

(Para obtener una descripción de cada valor, haga clic en el encabezado de definición de especificación anterior).

A continuación se muestra una ilustración del efecto de cada valor en un contenedor de dirección de fila.

fuente: W3C

¿Por qué el align-content solo funciona en contenedores flexibles de varias líneas?

En un contenedor flexible de una sola línea, el tamaño transversal de la línea es igual al tamaño transversal del contenedor. Esto significa que no hay espacio libre entre la línea y el contenedor. Como resultado, align-content puede tener efecto.

Aquí está la sección relevante de la especificación :

Solo los contenedores flexibles de varias líneas tienen espacio libre en el eje transversal para que las líneas se alineen, porque en un contenedor flexible de una sola línea, la única línea se estira automáticamente para llenar el espacio.

Parte 4: Ejemplos explicados

En el Ejemplo # 1, align-self funciona con flex-wrap: nowrap porque los elementos flex existen en un contenedor de una sola línea. Por lo tanto, hay una línea flexible y coincide con la altura del contenedor.

flex-container { display: flex; flex-wrap: nowrap; align-content: flex-start; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; } flex-item:last-child { align-self: flex-end; background-color: crimson; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

En el Ejemplo # 2, align-self falla porque existe en un contenedor de varias líneas ( flex-wrap: wrap ) y align-content está configurado en flex-start . Esto significa que las líneas flexibles se empaquetan estrechamente al comienzo del eje transversal, sin dejar espacio libre para que la align-self funcione.

flex-container { display: flex; flex-wrap: wrap; align-content: flex-start; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; } flex-item:last-child { align-self: flex-end; background-color: crimson; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

La explicación para el Ejemplo # 3 es la misma que para el Ejemplo # 1.

flex-container { display: flex; flex-wrap: nowrap; align-items: flex-end; align-content: flex-start; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

La explicación para el Ejemplo # 4 es la misma que para el Ejemplo # 2.

flex-container { display: flex; flex-wrap: wrap; align-items: flex-end; align-content: flex-start; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

El ejemplo # 5 es un contenedor de una sola línea. Como tal, el tamaño transversal de la línea flexible es igual al tamaño transversal del contenedor, sin dejar espacio adicional entre los dos. Por lo tanto, align-content , que alinea las líneas flexibles cuando hay espacio adicional en el eje transversal , no tiene ningún efecto.

flex-container { display: flex; flex-wrap: nowrap; align-content: center; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

La configuración inicial para align-content es stretch . Esto significa que si no se especifica ningún otro valor, el contenedor distribuirá el espacio disponible de manera uniforme entre las líneas flexibles. (Se crea un efecto similar en el eje principal cuando todos los elementos flex: 1 se flex: 1 )

Esta distribución de espacio entre líneas puede causar espacios amplios entre filas / columnas. Menos líneas resultan en espacios más anchos. Más líneas resultan en huecos más pequeños, ya que cada línea obtiene una parte más pequeña del espacio.

Para resolver este problema, cambie de align-content: stretch a align-content: flex-start . Esto agrupa las líneas (ver ejemplos # 2 y # 4 arriba). Por supuesto, esto también elimina cualquier espacio libre en la línea, y align-items y align-self ya no pueden funcionar.

Aquí hay una publicación relacionada: elimine el espacio (espacios) entre varias líneas de elementos flexibles cuando se envuelven

flex-container { display: flex; flex-wrap: wrap; /* align-content: center; */ width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

Como se explicó en los ejemplos anteriores, con align-content: stretch , puede haber espacio extra en las líneas flexibles, lo que permite que align-items align-self funcionen. Cualquier otro valor para align-content de align-content empacaría las líneas, eliminando espacio adicional y haciendo que align-items align-self y la align-self inútiles.

flex-container { display: flex; flex-wrap: wrap; /* align-content: center; */ width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; } flex-item:nth-child(even) { align-self: flex-end; background-color: crimson; }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>


En primer lugar, align-content es inútil si no hay ajuste:

w3c doc

La propiedad de alinear contenido alinea las líneas de un contenedor flexible dentro del contenedor flexible cuando hay espacio adicional en el eje transversal, de forma similar a cómo justify-content alinea elementos individuales dentro del eje principal. Tenga en cuenta que esta propiedad no tiene efecto en un contenedor flexible de una sola línea.

Además, en su segundo caso, align-self no falla. Es inútil porque las líneas internas han sido empaquetadas. Creemos un espacio para que el estilo pueda funcionar:

flex-container { display: flex; flex-wrap: wrap; align-content: flex-start; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; } flex-item:last-child { align-self: flex-end; background-color: crimson; } flex-item:nth-child(5) { height: 90px; /* added */ }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

Del mismo modo, en su cuarto ejemplo, el estilo está funcionando, si establece las condiciones donde se puede ver

flex-container { display: flex; flex-wrap: wrap; align-items: flex-end; align-content: flex-start; width: 250px; height: 250px; background-color: silver; } flex-item { flex: 0 0 50px; height: 50px; margin: 5px; background-color: lightgreen; } flex-item:nth-child(2),flex-item:nth-child(5) { height: 90px; /* added */ }

<flex-container> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> <flex-item></flex-item> </flex-container>

Finalmente, cuando comentas el contenido de alineación, vuelve a estirarse , es por eso que las líneas aumentan el tamaño para llenar el contenedor

estirar Las líneas se estiran para ocupar el espacio restante. Si el espacio libre restante es negativo, este valor es idéntico al inicio flexible. De lo contrario, el espacio libre se divide por igual entre todas las líneas, lo que aumenta su tamaño cruzado.