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
conalign-self
,align-items
yalign-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
ywrap-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
yalign-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
(soloalign-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ómojustify-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:
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.