Coloque el último artículo flexible al final del contenedor

97

Esta pregunta se refiere a un navegador con compatibilidad completa con css3, incluido flexbox.

Tengo un contenedor flexible con algunos artículos. Todos están justificados para flex-start pero quiero que el último .end elemento esté justificado para flex-end. ¿Existe una buena forma de hacerlo sin modificar el HTML y sin recurrir al posicionamiento absoluto?

.container {
  display: flex;
  flex-direction: column;
  outline: 1px solid green;
  min-height: 400px;
  width: 100px;
  justify-content: flex-start;
}
p {
  height: 50px;
  background-color: blue;
  margin: 5px;
}
<div class="container">
  <p></p>
  <p></p>
  <p></p>
  <p class="end"></p>
</div>

George Mauer
fuente
2
Si. Vea las autoilustraciones de los márgenes aquí: stackoverflow.com/a/33856609/3597276
Michael Benjamin
Posible duplicado de Alineación de un elemento a abajo con FlexBox
mfluehr

Respuestas:

204

Módulo de diseño de caja flexible - 8.1. Alineación con márgenes automáticos

Los márgenes automáticos en elementos flexibles tienen un efecto muy similar a los márgenes automáticos en el flujo de bloques:

  • Durante los cálculos de bases flexibles y longitudes flexibles, los márgenes automáticos se tratan como 0.

  • Antes de la alineación mediante justify-contenty align-self, cualquier espacio libre positivo se distribuye a los márgenes automáticos en esa dimensión.

Por lo tanto, podría utilizar margin-top: autopara distribuir el espacio entre los otros elementos y el último elemento.

Esto colocará el último elemento en la parte inferior.

p:last-of-type {
  margin-top: auto;
}

ejemplo vertical


Asimismo, también puede utilizar margin-left: autoo margin-right: autopara la misma alineación horizontalmente.

p:last-of-type {
  margin-left: auto;
}

ejemplo horizontal

Josh Crozier
fuente
1
¡Ah perfecto, no puedo creer que me lo perdiera! Especialmente vergonzoso ya que conozco totalmente el truco de usar margen automático para centrar verticalmente y lo uso todo el tiempo
George Mauer
1
@ j08691 No tengo una explicación formal de por qué funciona, pero es similar a cómo se puede usar margin: 0 autopara el centrado horizontal. Los elementos de Flexbox respetan el margen, y creo que margin: autoeso esencialmente colocará el elemento con el mayor espacio posible entre el hermano. Ver: w3.org/TR/css-flexbox-1/#auto-margins
Josh Crozier
2
@ jo8691 si no me equivoco, margin: autoen un elemento flexible le dice que cree tanto espacio como sea posible en esa dirección.
George Mauer
1
La especificación dice Prior to alignment via justify-content and align-self, any positive free space is distributed to auto margins in that dimension.
George Mauer
Estoy tratando de aprender más sobre flexbox, por lo que sería genial ver una referencia que describa este comportamiento. Particularmente que también es intencionado y no una peculiaridad o efecto secundario.
j08691
60

Este principio de caja flexible también funciona horizontalmente

Durante los cálculos de las bases flexibles y las longitudes flexibles, los márgenes automáticos se tratan como 0.
Antes de la alineación a través de justificar contenido y alinearse a sí mismo, cualquier espacio libre positivo se distribuye a los márgenes automáticos en esa dimensión.

Establecer un margen izquierdo automático para el último elemento hará el trabajo.

.last-item {
  margin-left: auto;
}

Ejemplo de código:

.container {
  display: flex;
  width: 400px;
  outline: 1px solid black;
}

p {
  height: 50px;
  width: 50px;
  margin: 5px;
  background-color: blue;
}

.last-item {
  margin-left: auto;
}
<div class="container">
  <p></p>
  <p></p>
  <p></p>
  <p class="last-item"></p>
</div>

Fragmento de Codepen

Esto puede resultar muy útil para los pies de página de escritorio.

Como hizo Envato aquí con el logo de la empresa.

Fragmento de Codepen

David Ben Dahan
fuente
3
No estoy seguro de por qué esto realmente funciona, pero me ayudó en un proyecto.
Louis345
4
¿Qué pasa si necesito que todos los elementos estén en el centro y el último en el lado derecho?
Illorian