align - En CSS Flexbox, ¿por qué no hay propiedades "justify-items" y "justify-self"?
justify self no work (5)
Métodos para alinear elementos flexibles a lo largo del eje principal
Como se indica en la pregunta:
Para alinear elementos flexibles a lo largo del eje principal hay una propiedad:
justify-content
Para alinear elementos flexibles a lo largo del eje transversal, hay tres propiedades:
align-content
, align-items .
La pregunta luego pregunta:
¿Por qué no hay
justify-items
yjustify-self
propiedades?
Una respuesta puede ser: porque no son necesarios.
La especificación flexbox proporciona dos métodos para alinear elementos flexibles a lo largo del eje principal:
-
La propiedad de palabra clave
justify-content
, y -
márgenes
auto
justificar-contenido
La propiedad justify
justify-content
alinea los elementos flexibles a lo largo del eje principal del contenedor flexible.
Se aplica al contenedor flexible pero solo afecta a los artículos flexibles.
Hay cinco opciones de alineación:
-
flex-start
flexible ~ Los artículos flexibles se empaquetan hacia el inicio de la línea. -
flex-end
flexible ~ Los artículos flexibles se empaquetan hacia el final de la línea. -
center
~ Los artículos flexibles se empaquetan hacia el centro de la línea. -
space-between
~ Los artículos flexibles están espaciados uniformemente, con el primer artículo alineado a un borde del contenedor y el último artículo alineado al borde opuesto. Los bordes utilizados por el primer y el último elemento dependen deflex-direction
y el modo de escritura (ltr
ortl
). -
space-around
~ Igual que elspace-between
excepto con espacios de tamaño medio en ambos extremos.
Márgenes automáticos
Con los
márgenes
auto
, los elementos flexibles pueden centrarse, separarse o agruparse en subgrupos.
A diferencia de
justify-content
, que se aplica al contenedor flexible, los márgenes
auto
van en elementos flexibles.
Funcionan consumiendo todo el espacio libre en la dirección especificada.
Alinee el grupo de elementos flexibles a la derecha, pero el primer elemento a la izquierda.
Escenario de la pregunta:
hacer que un grupo de elementos flexibles se alinee a la derecha (
justify-content: flex-end
) pero que el primer elemento se alinee a la izquierda (justify-self: flex-start
)Considere una sección de encabezado con un grupo de elementos de navegación y un logotipo. Con
justify-self
el logotipo podría alinearse a la izquierda mientras que los elementos de navegación permanecen a la derecha, y todo se ajusta sin problemas ("flexiona") a diferentes tamaños de pantalla.
Otros escenarios útiles:
Coloque un elemento flexible en la esquina
Escenario de la pregunta:
- colocando un elemento flexible en una esquina
.box { align-self: flex-end; justify-self: flex-end; }
.box { align-self: flex-end; justify-self: flex-end; }
Centre un elemento flexible vertical y horizontalmente
margin: auto
es una alternativa a
justify-content: center
y
align-items: center
.
En lugar de este código en el contenedor flexible:
.container {
justify-content: center;
align-items: center;
}
Puede usar esto en el elemento flexible:
.box56 {
margin: auto;
}
Esta alternativa es útil cuando se centra un elemento flexible que desborda el contenedor .
Centre un elemento flexible y centre un segundo elemento flexible entre el primero y el borde
Un contenedor flexible alinea los artículos flexibles mediante la distribución de espacio libre.
Por lo tanto, para crear un equilibrio igual , de modo que un elemento intermedio pueda centrarse en el contenedor con un único elemento al lado, se debe introducir un contrapeso.
En los ejemplos a continuación, se introducen los terceros elementos flexibles invisibles (recuadros 61 y 68) para equilibrar los elementos "reales" (recuadros 63 y 66).
Por supuesto, este método no es nada bueno en términos de semántica.
Alternativamente, puede usar un pseudo-elemento en lugar de un elemento DOM real. O puede usar el posicionamiento absoluto. Aquí se cubren los tres métodos: elementos flexibles centrales y de alineación inferior
NOTA: Los ejemplos anteriores solo funcionarán, en términos de centrado verdadero, cuando los elementos más externos tengan la misma altura / anchura. Cuando los artículos flexibles tienen diferentes longitudes, vea el siguiente ejemplo.
Centre un elemento flexible cuando los elementos adyacentes varían de tamaño
Escenario de la pregunta:
en una fila de tres elementos flexibles, fije el elemento central en el centro del contenedor (
justify-content: center
) y alinee los elementos adyacentes a los bordes del contenedor (justify-self: flex-start
yjustify-self: flex-end
)Tenga en cuenta que los valores
space-around
yspace-between
en la propiedadjustify-content
no mantendrán el elemento central centrado en relación con el contenedor si los elementos adyacentes tienen anchuras diferentes ( vea la demostración ).
Como se señaló, a menos que todos los elementos flexibles sean del mismo ancho o alto (dependiendo de
flex-direction
), el elemento central no puede estar verdaderamente centrado.
Este problema es un argumento sólido para una propiedad
justify-self
(diseñada para manejar la tarea, por supuesto).
#container {
display: flex;
justify-content: space-between;
background-color: lightyellow;
}
.box {
height: 50px;
width: 75px;
background-color: springgreen;
}
.box1 {
width: 100px;
}
.box3 {
width: 200px;
}
#center {
text-align: center;
margin-bottom: 5px;
}
#center > span {
background-color: aqua;
padding: 2px;
}
<div id="center">
<span>TRUE CENTER</span>
</div>
<div id="container">
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
</div>
<p>The middle box will be truly centered only if adjacent boxes are equal width.</p>
Aquí hay dos métodos para resolver este problema:
Solución # 1: Posicionamiento absoluto
La especificación flexbox permite el posicionamiento absoluto de los elementos flexibles . Esto permite que el elemento central esté perfectamente centrado, independientemente del tamaño de sus hermanos.
Solo tenga en cuenta que, como todos los elementos posicionados absolutamente, los elementos se eliminan del flujo de documentos . Esto significa que no ocupan espacio en el contenedor y pueden superponerse a sus hermanos.
En los ejemplos a continuación, el elemento central se centra con un posicionamiento absoluto y los elementos externos permanecen en flujo.
Pero se puede lograr el mismo diseño de manera inversa
justify-content: center
el elemento central con
justify-content: center
y posicione absolutamente los elementos externos.
Solución n. ° 2: Contenedores flexibles anidados (sin posicionamiento absoluto)
.container {
display: flex;
}
.box {
flex: 1;
display: flex;
justify-content: center;
}
.box71 > span { margin-right: auto; }
.box73 > span { margin-left: auto; }
/* non-essential */
.box {
align-items: center;
border: 1px solid #ccc;
background-color: lightgreen;
height: 40px;
}
<div class="container">
<div class="box box71"><span>71 short</span></div>
<div class="box box72"><span>72 centered</span></div>
<div class="box box73"><span>73 loooooooooooooooong</span></div>
</div>
Así es como funciona:
-
El div de nivel superior (
.container
) es un contenedor flexible. -
Cada elemento secundario div (
.box
) ahora es un elemento flexible. -
Cada elemento
.box
recibeflex: 1
para distribuir el espacio del contenedor por igual. - Ahora los elementos están consumiendo todo el espacio en la fila y tienen el mismo ancho.
-
Convierta cada elemento en un contenedor flexible (anidado) y agregue
justify-content: center
. -
Ahora cada elemento
span
es un elemento flexible centrado. -
Utilice los márgenes
auto
flexibles para desplazar elspan
exterior hacia la izquierda y hacia la derecha.
También puede renunciar a
justify-content
y usar márgenes
auto
exclusivamente.
Pero
justify-content
puede funcionar aquí porque los márgenes
auto
siempre tienen prioridad.
De la especificación:
8.1. Alineándose con márgenes
auto
Antes de la alineación a través de
justify-content
yalign-self
, cualquier espacio libre positivo se distribuye a los márgenes automáticos en esa dimensión.
justify-content: space-same (concepto)
Volviendo al
justify-content
de
justify-content
por un minuto, aquí hay una idea para una opción más.
-
space-same
~ Un híbrido despace-between
yspace-around
. Los elementos flexibles están espaciados de manera uniforme (comospace-between
), excepto que en lugar de espacios de tamaño medio en ambos extremos (comospace-around
), hay espacios de tamaño completo en ambos extremos.
Este diseño se puede lograr con
::before
y
::after
pseudo-elementos en el contenedor flexible.
(crédito: @oriol para el código y @crl para la etiqueta)
ACTUALIZACIÓN:
Los navegadores han comenzado a implementar el
space-evenly
, lo que cumple con lo anterior.
Vea esta publicación para más detalles:
igual espacio entre elementos flexibles
PLAYGROUND (incluye código para todos los ejemplos anteriores)
Considere el eje principal y el eje transversal de un contenedor flexible:
Fuente: W3C
Para alinear elementos flexibles a lo largo del eje principal hay una propiedad:
Para alinear elementos flexibles a lo largo del eje transversal, hay tres propiedades:
En la imagen de arriba, el eje principal es horizontal y el eje transversal es vertical. Estas son las direcciones predeterminadas de un contenedor flexible.
Sin embargo, estas direcciones pueden intercambiarse fácilmente con la propiedad de
flex-direction
.
/* main axis is horizontal, cross axis is vertical */
flex-direction: row;
flex-direction: row-reverse;
/* main axis is vertical, cross axis is horizontal */
flex-direction: column;
flex-direction: column-reverse;
(El eje transversal siempre es perpendicular al eje principal).
Mi punto al describir cómo funcionan los ejes es que no parece haber nada especial en ninguna dirección.
El eje principal, el eje transversal, ambos son iguales en términos de importancia y
flex-direction
hace que sea fácil cambiar de un lado a otro.
Entonces, ¿por qué el eje transversal obtiene dos propiedades de alineación adicionales?
¿Por qué el
align-content
align-items
consolidan en una propiedad para el eje principal?
¿Por qué el eje principal no obtiene una propiedad
justify-self
?
Escenarios donde estas propiedades serían útiles:
-
colocando un elemento flexible en la esquina del contenedor flexible
#box3 { align-self: flex-end; justify-self: flex-end; }
-
hacer que un grupo de elementos flexibles se alinee a la derecha (
justify-content: flex-end
) pero que el primer elemento se alinee a la izquierda (justify-self: flex-start
)Considere una sección de encabezado con un grupo de elementos de navegación y un logotipo. Con
justify-self
el logotipo podría alinearse a la izquierda mientras que los elementos de navegación permanecen a la derecha, y todo se ajusta sin problemas ("flexiona") a diferentes tamaños de pantalla. -
en una fila de tres elementos flexibles, fije el elemento central en el centro del contenedor (
justify-content: center
) y alinee los elementos adyacentes a los bordes del contenedor (justify-self: flex-start
yjustify-self: flex-end
)Tenga en cuenta que los valores
space-around
yspace-between
en la propiedadjustify-content
no mantendrán el elemento central centrado en relación con el contenedor si los elementos adyacentes tienen anchuras diferentes.
#container {
display: flex;
justify-content: space-between;
background-color: lightyellow;
}
.box {
height: 50px;
width: 75px;
background-color: springgreen;
}
.box1 {
width: 100px;
}
.box3 {
width: 200px;
}
#center {
text-align: center;
margin-bottom: 5px;
}
#center > span {
background-color: aqua;
padding: 2px;
}
<div id="center">
<span>TRUE CENTER</span>
</div>
<div id="container">
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
</div>
<p>note that the middle box will only be truly centered if adjacent boxes are equal width</p>
Al escribir estas líneas, no se menciona
justify
justify-self
o
justify
justify-items
en la
especificación de flexbox
.
Sin embargo, en el Módulo de alineación de cajas CSS , que es la propuesta inacabada del W3C para establecer un conjunto común de propiedades de alineación para su uso en todos los modelos de cajas, existe esto:
Fuente: W3C
Notarás que
justify-self
y
justify-items
están siendo considerados ...
pero no para flexbox
.
Terminaré reiterando la pregunta principal:
¿Por qué no hay propiedades "justify-items" y "justify-self"?
Esto se preguntó en la lista de estilo www, y Tab Atkins (editor de especificaciones) proporcionó una respuesta explicando por qué . Voy a elaborar un poco sobre eso aquí.
Para comenzar, supongamos inicialmente que nuestro contenedor flexible es de una sola línea (
flex-wrap: nowrap
).
En este caso, hay claramente una diferencia de alineación entre el eje principal y el eje transversal: hay varios elementos apilados en el eje principal, pero solo un elemento apilado en el eje transversal.
Por lo tanto, tiene sentido tener un "align-self" personalizable por elemento en el eje transversal (ya que cada elemento está alineado por separado, por sí solo), mientras que no tiene sentido en el eje principal (ya que allí, el los artículos están alineados colectivamente).
Para flexbox multilínea, la misma lógica se aplica a cada "línea flexible". En una línea determinada, los elementos se alinean individualmente en el eje transversal (ya que solo hay un elemento por línea, en el eje transversal), en comparación con el eje principal.
Aquí hay otra forma de expresarlo: por lo tanto,
todas
las propiedades de
*-content
y
*-content
tratan sobre cómo distribuir espacio extra alrededor de las cosas.
Pero la diferencia clave es que las versiones
*-self
son para casos en los que
solo hay una cosa en ese eje
, y las versiones
*-content
son para cuando potencialmente hay
muchas cosas en ese eje
.
Los escenarios de una cosa versus muchas cosas son diferentes tipos de problemas, por lo que tienen diferentes tipos de opciones disponibles, por ejemplo, los valores de
space-around
/
space-between
tienen sentido para el
*-content
, pero no para
*-self
SO: En el eje principal de un flexbox, hay muchas cosas para distribuir el espacio.
Entonces, una propiedad
*-content
tiene sentido allí, pero no una propiedad
*-self
.
Por el contrario, en el eje transversal, tenemos una propiedad de
*-content
y
*-content
.
Uno determina cómo distribuiremos el espacio alrededor de las
muchas
líneas flexibles (
align-content
), mientras que el otro (
align-self
) determina cómo distribuir el espacio alrededor de los elementos flexibles
individuales
en el eje transversal, dentro de una línea flexible dada.
(Estoy ignorando las propiedades
*-items
aquí, ya que simplemente establecen valores predeterminados para
*-self
.)
Hay
justify-self
, pero en Chrome Canary, no en la versión estable de Chrome.
Incluso hay
justify-items
:
Pero por lo que puedo decir, esas propiedades tampoco funcionan. Entonces, probablemente Google lo guardó de antemano para futuras versiones de CSS. Solo puedo esperar que agreguen las propiedades pronto.
Sé que esto no es una respuesta, pero me gustaría contribuir a este asunto por lo que vale.
Sería genial si pudieran lanzar justify
justify-self
para flexbox para que sea realmente flexible.
Creo que cuando hay varios elementos en el eje, la forma más lógica de comportarse para
justify-self
es alinearse con sus vecinos más cercanos (o borde) como se demuestra a continuación.
Realmente espero que el W3C se dé cuenta de esto y al menos lo considere. =)
De esta manera, puede tener un elemento realmente centrado, independientemente del tamaño del cuadro izquierdo y derecho. Cuando una de las cajas alcanza el punto de la caja central, simplemente la empujará hasta que no haya más espacio para distribuir.
La facilidad para crear diseños increíbles es infinita, eche un vistazo a este ejemplo "complejo".
Sé que esto no usa flexbox, pero para el caso de uso simple de tres elementos (uno a la izquierda, uno al centro, uno a la derecha), esto se puede lograr fácilmente usando
display: grid
en el padre,
grid-area: 1/1/1/1;
en los niños, y
justify-self
para el posicionamiento de esos niños.
<div style="border: 1px solid red; display: grid; width: 100px; height: 25px;">
<div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: left;"></div>
<div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: center;"></div>
<div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: right;"></div>
</div>