En CSS Flexbox, ¿por qué no hay propiedades" justify-items "y" justify-self"?
Considere el eje principal y el eje transversal de un contenedor flexible:
Fuente: W3C
Para alinear los elementos flex a lo largo del eje principal hay una propiedad:
Para alinear los elementos flex 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 flex.
Sin embargo, estas direcciones se pueden intercambiar fácilmente con el flex-direction
propiedad.
/* 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 es siempre perpendicular al eje principal.)
Mi punto al describir cómo los ejes' el trabajo es que no parece haber nada especial en ninguna dirección. Eje principal, eje transversal, ambos son iguales en términos de importancia y flex-direction
hace que sea fácil cambiar hacia adelante y hacia atrás.
Entonces, ¿por qué el eje transversal obtiene dos propiedades de alineación adicionales?
¿Por qué align-content
y align-items
se 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:
Colocar un elemento flex en la esquina del contenedor flex
#box3 { align-self: flex-end; justify-self: flex-end; }
-
Hacer que un grupo de elementos flex 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 se quedan a la derecha, y todo se ajusta suavemente ("flexiona") a diferentes pantallas Tamaño. -
En una fila de tres elementos flexibles, coloque 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á 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 momento de escribir este artículo, no hay mención de justify-self
o justify-items
en la especificación flexbox.
Sin embargo, en el Módulo CSS Box Alignment , 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 caja, está esto:
Fuente: W3C
Notarás que justify-self
y justify-items
están siendo considerados... , pero no para flexbox.
Terminaré reiterando la pregunta principal: {[27]]}
¿Por qué no hay propiedades "justify-items" y "justify-self"?
5 answers
Métodos para alinear Elementos Flexibles a lo largo del Eje Principal
Como se indica en la pregunta:
Para alinear los elementos flex a lo largo del eje principal hay una propiedad:
justify-content
Para alinear los elementos flex a lo largo del eje transversal hay tres propiedades:
align-content
,align-items
yalign-self
.
La pregunta entonces hace: {[70]]}
¿Por qué no hay propiedades
justify-items
yjustify-self
?
Una respuesta puede ser: Porque no son necesarios.
La especificación flexbox proporciona dos métodos para alinear elementos flex a lo largo del eje principal:
- La propiedad de la palabra clave
justify-content
, y -
auto
márgenes
Justify-contenido
El justify-content
la propiedad alinea los elementos flex a lo largo del eje principal del contenedor flex.
Se aplica al contenedor flex pero solo afecta a los elementos flexibles.
Hay cinco opciones de alineación:
-
flex-start
~ Los artículos Flex se empaquetan hacia el inicio de la línea. -
flex-end
~ 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 alinear. -
space-between
~ Los elementos Flex están espaciados uniformemente, con el primer elemento alineado a un borde del contenedor y el último elemento alineado al borde opuesto. Los bordes utilizados por el primer y último elemento depende deflex-direction
y modo de escritura (ltr
ortl
). -
space-around
~ Igual quespace-between
excepto con espacios de tamaño medio en ambos final.
Márgenes automáticos
Con auto
margins , los elementos flex se pueden centrar, espaciar o empaquetar en subgrupos.
A diferencia de justify-content
, que se aplica al contenedor flex, auto
los márgenes van en los elementos flex.
Funcionan consumiendo todo el espacio libre en la dirección especificada.
Alinear el grupo de elementos flex a la derecha, pero el primer elemento a la izquierda
Escenario desde la pregunta:
Hacer que un grupo de elementos flex se alinee a la derecha (
justify-content: flex-end
) pero haga 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 los elementos de navegación permanecen extrema derecha, y todo se ajusta suavemente ("flexiona") a diferentes tamaños de pantalla.
Otros escenarios útiles:
Coloque un elemento flexible en la esquina
Escenario de la pregunta:
- colocar un elemento flexible en una esquina
.box { align-self: flex-end; justify-self: flex-end; }
Centro 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 flex:
.container {
justify-content: center;
align-items: center;
}
Puede usar esto en el elemento flex:
.box56 {
margin: auto;
}
Esta alternativa es útil cuando centrar un elemento flexible que desborda el contenedor.
Centrar un elemento flexible, y centrar un segundo elemento flexible entre el primero y el borde
A flex container alinea los elementos flex distribuyendo el espacio libre.
Por lo tanto, para crear equilibrio igual, de modo que un elemento central se pueda centrar en el contenedor con un solo elemento al lado, se debe introducir un contrapeso.
En los ejemplos siguientes, se introducen los elementos invisibles de la tercera flexión (casillas 61 y 68) para equilibrar los elementos "reales" (casillas 63 y 66).
Por supuesto, este método es nada grande en términos de semántica.
Alternativamente, puede usar un pseudo-elemento en lugar de un elemento DOM real. O puedes usar posicionamiento absoluto. Los tres métodos están cubiertos aquí: Centro y parte inferior-alinear elementos flexibles
NOTA: Los ejemplos anteriores solo funcionarán, en términos de centrado verdadero, cuando los elementos más externos sean iguales altura / ancho. Cuando los elementos flex tienen diferentes longitudes, consulte el siguiente ejemplo.
Centro a elemento flexible cuando los elementos adyacentes varían en tamaño
Escenario de la pregunta:
En una fila de tres elementos flexibles, coloque el elemento central en el centro del contenedor (
justify-content: center
) y alinee el elemento adyacente elementos 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 diferentes anchuras (ver demo ).
Como se ha señalado, a menos que todos los elementos flex sean de igual ancho o alto (dependiendo de flex-direction
), el elemento central no puede estar verdaderamente centrado. Este problema hace un caso fuerte 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 para 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 absolutamente posicionados, los elementos se eliminan del flujo de documentos . Esto significa que no ocupan espacio en el contenedor y pueden superponerse con sus hermanos.
En los ejemplos siguientes, el elemento central se centra con posicionamiento absoluto y los elementos externos permanecen en flujo. Pero el mismo diseño se puede lograr de manera inversa: Centre el elemento central con justify-content: center
y coloque absolutamente los elementos exteriores.
Solució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 div hijo (
.box
) es ahora un elemento flexible. - Cada
.box
artículo se daflex: 1
con el fin de distribuir el espacio del contenedor por igual. - Ahora los elementos están consumiendo todo el espacio en la fila y tienen el mismo ancho.
- Haga que cada elemento sea un contenedor flexible (anidado) y agregue
justify-content: center
. - Ahora cada elemento
span
es un elemento flex centrado. - Utilice los márgenes flex
auto
para desplazar losspan
exteriores a la izquierda y a la derecha.
También puedes renunciar a justify-content
y usar márgenes auto
exclusivamente.
Pero justify-content
puede funcionar aquí porque auto
los márgenes siempre tienen prioridad. De la especificación:
8.1. Alineación con
auto
márgenesAntes de la alineación vía
justify-content
yalign-self
, cualquier el espacio libre positivo se distribuye a los márgenes automáticos en esa dimensión.
Justify-content: espacio-mismo (concepto)
Volviendo a 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 Flex están espaciados uniformemente (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 flex.
(crédito: @oriol para el código, y @crl para la etiqueta)
ACTUALIZACIÓN: Los navegadores han comenzado a implementar space-evenly
, que logra lo anterior. Ver este post para más detalles: Espacio igual entre los elementos flex
PLAYGROUND (incluye código para todos los ejemplos anteriores)
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-12-19 00:18:44
Sé que esto no es una respuesta, pero me gustaría contribuir a este asunto por lo que vale. Sería genial si pudieran liberar justify-self
para flexbox para hacerlo realmente flexible.
Creo que cuando hay varios elementos en el eje, la forma más lógica para que justify-self
se comporte es alinearse con sus vecinos más cercanos (o borde) como se muestra a continuación.
Realmente espero, W3C toma nota de esto y al menos lo considerará. =)
De esta manera puede tener un elemento que está verdaderamente centrado independientemente del tamaño de la caja izquierda y derecha. 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 de hacer diseños impresionantes son infinitas, echa un vistazo a este ejemplo "complejo".
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
2018-08-23 01:01:57
Esto se preguntó en la lista de estilo www, y Tab Atkins (editor de especificaciones) proporcionó una respuesta explicando por qué. Me explayaré un poco sobre eso aquí.
Para empezar, asumamos inicialmente que nuestro contenedor flex 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 there hay varios elementos apilados en el eje principal, pero solo un elemento apilados en el eje transversal. Así que tiene sentido tener un personalizable-por-elemento "align-self" en el eje transversal (ya que cada elemento se alinea por separado, por sí solo), mientras que no tiene sentido en el eje principal (ya que allí, los elementos se alinean colectivamente).
Para flexbox multilínea, la misma lógica se aplica a cada "línea flex". En una línea dada, los elementos se alinean individualmente en el eje transversal (ya que solo hay un elemento por línea, en el eje transversal), frente a colectivamente en el eje principal.
Aquí hay otra forma de expresarlo: entonces, todo de las propiedades *-self
y *-content
se trata de cómo distribuir espacio adicional alrededor de las cosas. Pero la diferencia clave es que las versiones *-self
son para casos donde hay solo una cosa en ese eje, y las versiones *-content
son para cuando hay potencialmente muchas cosas en ese eje. Los escenarios de una cosa vs. muchas cosas son diferentes tipos de problemas, y por lo tanto tienen diferentes tipos de opciones disponibles for por ejemplo, el space-around
/ space-between
los valores tienen sentido para *-content
, pero no para *-self
.
ASÍ QUE: En el eje principal de un flexbox, hay muchas cosas para distribuir el espacio. Así que una propiedad *-content
tiene sentido allí, pero no una propiedad *-self
.
En contraste, en el eje transversal, tenemos ambas propiedades *-self
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 elementos flexibles individuales en el eje transversal, dentro de un dada la línea flex.
(Estoy ignorando las propiedades *-items
aquí, ya que simplemente establecen valores predeterminados para *-self
.)
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
2018-06-27 18:54:26
Hay justify-self
, pero en Chrome Canary, no en la versión estable de Chrome. Hay incluso justify-items
:
Pero por lo que puedo decir esas propiedades tampoco funcionan. Así que probablemente Google lo guardó de antemano para futuras versiones de CSS. Solo puedo esperar que agreguen las propiedades pronto.
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
2016-12-16 17:25:29
Hay justify-items
.
Creo que es una característica nueva. La compatibilidad del navegador es algo deficiente.
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
2018-05-20 11:13:48