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:

introduzca la descripción de la imagen aquí                                                                                                                        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 y justify-self: flex-end).

    Tenga en cuenta que los valores space-around y space-between en la propiedad justify-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>

JsFiddle versión


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:

introduzca la descripción de la imagen aquí                                                                                                                         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"?

Author: Michael_B, 2015-09-13

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 y align-self.

La pregunta entonces hace: {[70]]}

¿Por qué no hay propiedades justify-items y justify-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:

  1. La propiedad de la palabra clave justify-content, y
  2. 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.

    introduzca la descripción de la imagen aquí

  • flex-end ~ Los artículos flexibles se empaquetan hacia el final de la línea.

    introduzca la descripción de la imagen aquí

  • center ~ Los artículos flexibles se empaquetan hacia el centro de la alinear.

    introduzca la descripción de la imagen aquí

  • 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 de flex-direction y modo de escritura (ltr o rtl).

    introduzca la descripción de la imagen aquí

  • space-around ~ Igual que space-between excepto con espacios de tamaño medio en ambos final.

    introduzca la descripción de la imagen aquí


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.

introduzca la descripción de la imagen aquí

introduzca la descripción de la imagen aquí


Otros escenarios útiles:

introduzca la descripción de la imagen aquí

introduzca la descripción de la imagen aquí

introduzca la descripción de la imagen aquí


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; }

introduzca la descripción de la imagen aquí


Centro un elemento flexible vertical y horizontalmente

introduzca la descripción de la imagen aquí

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).

introduzca la descripción de la imagen aquí

introduzca la descripción de la imagen aquí

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 y justify-self: flex-end).

    Tenga en cuenta que los valores space-around y space-between en la propiedad justify-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.

introduzca la descripción de la imagen aquí

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 da flex: 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 autopara desplazar los span 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árgenes

Antes de la alineación vía justify-content y align-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 de space-between y space-around. Los elementos Flex están espaciados uniformemente (como space-between), excepto que en lugar de espacios de tamaño medio en ambos extremos (como space-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.

introduzca la descripción de la imagen aquí

(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)

 841
Author: Michael_B,
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á. =)

introduzca la descripción de la imagen aquí

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.

introduzca la descripción de la imagen aquí

La facilidad de hacer diseños impresionantes son infinitas, echa un vistazo a este ejemplo "complejo".

introduzca la descripción de la imagen aquí

 88
Author: Mark,
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 *-selfson para casos donde hay solo una cosa en ese eje, y las versiones *-contentson 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.)

 15
Author: dholbert,
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:

introduzca la descripción de la imagen aquí

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.

 0
Author: Green,
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.

 -3
Author: Alex Tan,
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