¿Cómo funciona flex-wrap con align-self, align-items y align-content?
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
De manera similar, ¿por qué align-items
funciona aquí (wrap 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 align-content
no centrará verticalmente los elementos flex 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 wrap está habilitado y align-content
se deja fuera, el contenedor crea amplios espacios entre 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 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
conalign-self
,align-items
yalign-content?
2 answers
Respuesta corta
Aunque la propiedad flex-wrap
parece bastante básica – controla si los elementos flex pueden envolver – en realidad tiene un gran impacto en todo el diseño de flexbox.
La propiedad flex-wrap
determina el tipo de contenedor flex que utilizará.
-
flex-wrap: nowrap
crea un contenedor flexible de una línea -
flex-wrap: wrap
ywrap-reverse
crear un flex de varias líneas contenedor
Las propiedades align-items
y align-self
funcionan tanto en contenedores de una línea como en contenedores de varias líneas. Sin embargo, solo pueden tener un efecto cuando hay espacio libre en el eje transversal de la línea flex.
La propiedad align-content
solo funciona en contenedores multilínea. Se ignora en contenedores de una sola línea.
Explicación
La especificación flexbox proporciona cuatro propiedades de palabras clave para alinear flex items:
align-items
align-self
align-content
justify-content
Para entender las funciones de estas propiedades es importante entender 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) e eje y (vertical).
Fuente: Wikipedia
Los elementos secundarios de un contenedor flex, conocidos como "elementos flex", se pueden alinear en cualquier dirección.
Esta es la alineación flex en su nivel más fundamental.
El Principal y la Cruz Ejes
La superposición de los ejes x e y son, en el diseño flexible, los ejes mainy cross.
Por defecto, el eje principal es horizontal (eje x), y el eje transversal es vertical (eje y). Esa es la configuración inicial, como se define en el flexbox especificación.
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 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 flex-direction
. Esta propiedad controla la dirección del eje principal; determina si los elementos flex se alinean vertical u horizontalmente.
De la especificación:
5.1. Dirección de flujo flexible: el
flex-direction
propiedadLa propiedad
flex-direction
especifica cómo se colocan los elementos flex el contenedor flex, configurando la dirección del contenedor flex eje principal. Esto determina la dirección en la que se colocan los elementos flex fuera.
Hay cuatro valores para la propiedad 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 elementos flex existen en una línea, conocida como "línea flex".
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 flex de una sola línea, en el que los elementos flex se ven obligados a permanecer en una sola línea (incluso si desbordan el contenedor).
La imagen de arriba tiene una línea flex.
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>
Flex de Varias Líneas Contenedor
flex-wrap: wrap
o wrap-reverse
establece un contenedor flex multilínea, en el que los elementos flex 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: Alineación de palabras clave Propiedades
Las propiedades se asignan a los Ejes Principal y Transversal (no X e Y)
Mientras que la propiedad flex-direction
controla la dirección en la que se presentan los elementos flex, hay 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.
El justify-content
la propiedad funciona solo en el eje principal.
Las tres propiedades align-*
funcionan solo en el eje transversal.
Es un error común asumir que estas propiedades están fijadas a los ejes x e y. Por ejemplo, justify-content
es siempre horizontal, y align-items
es siempre 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 este post es la alineación de ejes transversales. Para una explicación de alineación del eje principal y la propiedad justify-content
, ver este post:
Definiciones
La especificación flexbox proporciona tres propiedades de palabras clave para la alineación de ejes transversales:
align-items
align-self
align-content
align-items
/ align-self
La propiedad align-items
aligns flex elementos a lo largo del eje transversal de la línea flex. Se aplica a los contenedores flexibles.
La propiedad align-self
se usa para anular align-items
en elementos flex individuales. Se aplica a los elementos flexibles.
Aquí está la definición de la especificación:
8.3. Alineación de ejes transversales: el
align-items
yalign-self
propiedadesLos elementos flexibles se pueden alinear en el eje transversal de la línea actual del contenedor flexible, similar a
justify-content
pero en la perpendicular dirección.align-items
establece la alineación predeterminada para todos los artículos de flex container.align-self
permite esta alineación predeterminada para ser anulado para elementos flexibles individuales.
Hay seis valores posibles para align-items
/ align-self
:
flex-start
flex-end
center
baseline
stretch
-
auto
(align-self
únicamente)
(Para una descripción de cada valor, haga clic en el encabezado definición de especificación arriba.)
El valor inicial de align-items
es stretch
, lo que significa que los elementos flex expandirán toda la longitud 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 una dirección de fila contenedor.
source: W3C
align-content
Esta propiedad es ligeramente más compleja que align-items
y align-self
.
Aquí está la definición de la especificación:
8.4. Líneas flexibles de embalaje: el
align-content
propiedadLa propiedad
align-content
alinea las líneas de un contenedor flexible dentro el contenedor flexible cuando hay espacio adicional en el eje transversal, similar a cómojustify-content
alinea elementos individuales dentro de la eje principal. Tenga en cuenta que esta propiedad no tiene ningún efecto en una flexión de una sola línea contenedor.
En contraste con align-items
y align-self
, que mueven elementos flexibles dentro de su línea, align-content
mueve las líneas flexibles dentro del contenedor.
Hay los seis valores posibles para align-content
:
flex-start
flex-end
center
space-between
-
space-around
stretch
(Para una descripción de cada valor, haga clic en el encabezado de definición de especificaciones arriba.)
A continuación se muestra una ilustración del efecto de cada valor en una dirección de fila contenedor.
source: W3C
¿Por qué align-content
funciona solo en contenedores flex multilínea?
En un contenedor flexible de una sola línea, el tamaño de cruz de la línea es igual al tamaño de cruz del contenedor. Esto significa que no hay espacio libre entre la línea y el contenedor. Como resultado, align-content
no puede tener ningún efecto.
Aquí está la sección relevante de la especificación :
Solo los contenedores flex de varias líneas tienen espacio libre en el eje transversal para que las líneas se alineen, porque en un contenedor flex 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 multilínea(flex-wrap: wrap
) y align-content
se establece en flex-start
. Esto significa que las líneas flexibles se empaquetan firmemente al comienzo del eje transversal, sin dejar espacio libre para align-self
para trabajo.
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 por Ejemplo #3 es la misma que por 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 por Ejemplo #4 es la misma que por 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 de la cruz de la línea de flexión es igual a la tamaño cruzado 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 está teniendo 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>
El ajuste 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 obtienen flex: 1
.)
Esta distribución del espacio entre líneas puede causar grandes espacios entre filas / columnas. Menos líneas resultan en espacios más amplios. Más líneas dan como resultado espacios más pequeños, ya que cada línea obtiene una porción más pequeña del espacio.
Para resolver este problema cambie de align-content: stretch
a align-content: flex-start
. Esto empaqueta las líneas juntas(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 trabajo.
Aquí hay un post relacionado: Eliminar el espacio (espacios) entre múltiples 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 ejemplos anteriores, con align-content: stretch
, puede haber espacio adicional en las líneas flexibles, lo que permite que align-items
y align-self
funcionen. Cualquier otro valor para align-content
empaquetaría las líneas, eliminando espacio adicional, y haciendo align-items
y align-self
inútil.
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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:10
En primer lugar, align-content es inútil si no hay wrap:
La propiedad align-content alinea las líneas de un contenedor flex dentro del contenedor flex cuando hay espacio adicional en el eje transversal, de manera similar a como justify-content alinea elementos individuales dentro del eje principal. Tenga en cuenta que esta propiedad no tiene ningún efecto en un contenedor flexible de una sola línea.
Además, en su segundo caso, align-self no está fallando. Es inútil porque el las líneas interiores han sido embaladas. Vamos a crear 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 4º 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 align-content, vuelve a stretch , es por eso que las líneas aumentan el tamaño para llenar el contenedor
Estirar Las líneas se extienden para ocupar el espacio restante. Si el espacio libre sobrante es negativo, este valor es idéntico a flex-start. De lo contrario, el espacio libre se divide por igual entre todas las líneas, aumentando su tamaño de cruz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-05 21:22:36