Caja flexible: alinee la última fila con la cuadrícula

379

Tengo un diseño simple de caja flexible con un contenedor como:

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

Ahora quiero que los elementos en la última fila estén alineados con el otro. justify-content: space-between;debe usarse porque el ancho y la altura de la cuadrícula se pueden ajustar.

Actualmente parece

El elemento en la parte inferior derecha debe estar en el medio

Aquí, quiero que el elemento en la parte inferior derecha esté en la "columna central". ¿Cuál es la forma más sencilla de lograr eso? Aquí hay un pequeño jsfiddle que muestra este comportamiento.

.exposegrid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.exposetab {
  width: 100px;
  height: 66px;
  background-color: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(0, 0, 0, 0.4);
  border-radius: 5px;
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
  margin-bottom: 10px;
}
<div class="exposegrid">
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
</div>

Thorben Croisé
fuente
Comprueba mi solución aquí Creo que funciona bien sin trucos, solo matemáticas: stackoverflow.com/questions/18744164/…
Sebastien Lorber
55
Alternativamente, use podría usar el módulo de cuadrícula css más nuevo , que no tiene este problema
Danield
1
Agregué una solución JS genérica para casos en los que el ancho del elemento secundario es variable, lo que también hace que el número de elementos en la fila sea variable.
tao

Respuestas:

417

Agregue uno ::afterque rellene automáticamente el espacio. No es necesario contaminar su HTML. Aquí hay un codepen que lo muestra: http://codepen.io/DanAndreasson/pen/ZQXLXj

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid::after {
  content: "";
  flex: auto;
}
Dan Andreasson
fuente
17
¿Sería posible hacer que funcione con el espacio de alguna manera?
Tom
61
@DanAndreasson Hay dos problemas, no comienza desde la izquierda (como el espacio intermedio), y también el espacio entre los elementos de la última fila es diferente al de la fila anterior (simulando algunos elementos de ancho fijo en "cualquier tamaño" cuadrícula - se relaciona con ambos) ... codepen.io/anon/pen/gPoYZE Lo que quería es mantener la "estrategia" (espacio alrededor o espacio intermedio) pero comenzar desde la izquierda como en las líneas anteriores ... I Quería saber si es posible generalizar su increíble solución.
Tom
44
Esto sólo funciona porque los artículos tienen acolchado al espacio ellos y los anchos de porcentaje combinado igual a 100% para cada conjunto de 4. En este codepen Quité justify-content: space-between;de .gridy se retira .grid:aftery funciona de la misma. Ahora si intentaste algo como esto, se rompe totalmente. Observe que los anchos para cada conjunto de 4 no suman 100%. En el violín del OP, los anchos se configuran en px para que su solución no funcione en esta situación.
Jacob Alvarez
22
Al probar esta solución, inicialmente, los elementos que faltaban en la última fila no se distribuyeron correctamente space-between. Sin embargo, cuando configuro el flex-basisde .grid:afteral mismo tamaño que los otros elementos en la cuadrícula (por punto de interrupción, anulando el código de módulo predeterminado / base anterior), la última fila se extendió correctamente. Parece funcionar en Safari, iOS, Firefox, Chrome (necesito probar IE) y mi tamaño de fila más grande es 3 en mi implementación inicial.
webbower
8
Para mis necesidades, esto funcionó con la siguiente modificación: { content: "";flex: 0 0 32%;max-width: 480px;}y cambié el ancho máximo con cambios de consulta de medios para que la cuadrícula fuera perfecta en todos los anchos.
Colin Wiseman
160

Una técnica sería insertar una cantidad de elementos adicionales (tantos como la cantidad máxima de elementos que alguna vez esperas tener en una fila) que tienen altura cero. El espacio todavía está dividido, pero las filas superfluas colapsan en nada:

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

En el futuro, esto se puede lograr mediante el uso de múltiples ::after(n) .

dalgard
fuente
11
Desafortunadamente, esto contamina el marcado de una manera no semántica, pero funciona totalmente. : SI desearía conocer alguna otra forma de replicar este comportamiento, flexbox o de otro tipo, que no requiriera elementos no semánticos.
Ryan Norbauer
33
De acuerdo, está sucio, pero funciona, y es menos hacky que muchos hacks. Tóquelo, lo estoy usando, hasta que :: after (12) obtenga soporte, o agreguen algunas opciones de justificación adicionales. Es una verdadera lástima ya que la forma en que justifica flexbox funciona en este momento es simplemente incorrecta Si estuviera justificando un párrafo de texto, nunca trataría de justificar la última línea. Definitivamente debería haber sido una opción, no puedo creer que se hayan perdido esto.
Codemonkey
44
Se me ocurrió una solución única de CSS ... la advertencia es que solo puede dar cuenta de dos elementos faltantes, por lo que solo funcionará de forma segura en una cuadrícula flexible con un máximo de tres elementos por fila de ajuste. Demostración: codepen.io/lukejacksonn/pen/dozqVq El principio aquí es usar pseudoelementos como hijos adicionales y darles la misma propiedad flexible que los elementos del contenedor.
lukejacksonn
8
@Codemonkey Jesus. Solo comencé a usar flexbox pensando en cómo eliminaré todos estos trucos destinados a alinear esos bloques en línea dentro de una cuadrícula, ¡y ahora resulta que simplemente no es posible! Llegué a ese bloque de inmediato, alcanzando los límites que pensé que casi nunca alcanzaría felizmente resolviendo todos estos viejos problemas CSS sin solución. No tan rápido, supongo. Solo tomó 20 años obtener un centrado vertical adecuado; ciertamente podemos esperar. Jesús, parece una tarea tan simple ...
Andrey
3
@dalgard No lo creo. Ver mi comentario .
Jacob Alvarez
109

Como han mencionado otros carteles: no hay una forma limpia de alinear a la izquierda la última fila con flexbox (al menos según las especificaciones actuales)

Sin embargo, para lo que vale: con el Módulo de diseño de cuadrícula CSS, esto es sorprendentemente fácil de producir:

Básicamente, el código relevante se reduce a esto:

ul {
  display: grid; /* 1 */
  grid-template-columns: repeat(auto-fill, 100px); /* 2 */
  grid-gap: 1rem; /* 3 */
  justify-content: space-between; /* 4 */
}

1) Convertir el elemento contenedor en un contenedor de cuadrícula

2) Establezca la cuadrícula con columnas automáticas de ancho 100px. (Tenga en cuenta el uso de autocompletar (como se indica en este documento auto-fit, que (para un diseño de 1 fila) contrae las pistas vacías a 0), lo que hace que los elementos se expandan para ocupar el espacio restante. 'diseño cuando la cuadrícula tiene solo una fila, que en nuestro caso no es lo que queremos (consulte esta demostración para ver la diferencia entre ellos).

3) Establezca espacios / canales para las filas y columnas de la cuadrícula, aquí, dado que desea un diseño de 'espacio intermedio', el espacio en realidad será un espacio mínimo porque crecerá según sea necesario.

4) Similar a flexbox.

Codepen Demo (Cambiar tamaño para ver el efecto)

Danield
fuente
44
Buena solución El único problema es que no funciona con IE10 / 11.
zendu
1
Al respecto auto-fit, hubo un error en Chrome 57-60 (y en los navegadores basados ​​en su motor, como Samsung Internet 6.0) porque la especificación era un poco ambigua en ese momento. Ahora se ha aclarado la especificación y las nuevas versiones de Chrome se procesan auto-fitcorrectamente, pero los navegadores con motores antiguos todavía están en uso, así que tenga cuidado con este valor.
Ilya Streltsyn
44
A la luz de las posibilidades actuales, esta debería ser la respuesta aceptada. El uso de :afterpseudoelementos puede conducir a resultados no deseados en casos extremos.
Paul
2
@ Danield esta sugerencia me ayudó mucho, ¡gracias!
Krys
44
Esta debería ser la respuesta aceptada. Lo combinaría con flexbox como alternativa, en el espíritu de la mejora progresiva: los navegadores que no admiten la cuadrícula mostrarían la versión de flexbox, que es lo suficientemente cercana para mí.
Palantir
27

Sin ningún marcado adicional, solo agregar ::afterfuncionó para mí especificando el ancho de la columna.

.grid {
  display:flex;
  justify-content:space-between;
  flex-wrap:wrap;
}
.grid::after{
  content: '';
  width: 10em // Same width of .grid__element
}
.grid__element{
  width:10em;
}

Con el HTML como este:

<div class=grid">
   <div class="grid__element"></div>
   <div class="grid__element"></div>
   <div class="grid__element"></div>
</div>
Nicolás Arévalo
fuente
99
Esto es interesante, pero no del todo correcto. el problema surge cuando se trata de más de dos elementos en la fila inferior: el espacio que emerge entre los elementos en las filas anteriores nunca emerge en la última; los artículos están empaquetados juntos, negando la utilidad original del espacio intermedio.
John Haugeland
incluso mejor si usas en flex-basis: 10emlugar de ancho.
beytarovski
14

No puedes Flexbox no es un sistema de cuadrícula. No tiene las construcciones del lenguaje para hacer lo que está pidiendo, al menos no si está usando justify-content: space-between. Lo más cercano que puede obtener con Flexbox es usar la orientación de la columna, que requiere establecer una altura explícita:

http://cssdeck.com/labs/pvsn6t4z (nota: prefijos no incluidos)

ul {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 4em;
}

Sin embargo, sería más simple usar columnas, que tienen un mejor soporte y no requieren establecer una altura específica:

http://cssdeck.com/labs/dwq3x6vr (nota: prefijos no incluidos)

ul {
  columns: 15em;
}
cimmanon
fuente
2
Hay una manera; mira mi respuesta
dalgard
@dalgard, su respuesta es una solución alternativa, no una solución verdadera. La respuesta de Cimmanon es correcta.
Jonás
1
@ Jonás, creo que "técnica" es una descripción justa de mi respuesta. Ciertamente ha funcionado como una solución para muchas personas, incluido el autor de la pregunta.
dalgard
2
@dalgard No cambia el hecho de que Flexbox no proporciona las construcciones del lenguaje para hacer lo que se le pide. Además, argumentaría que agregar elementos falsos es una práctica extremadamente sucia, al igual que usar tablas para el diseño.
cimmanon
44
No es bonito, pero el desarrollo front-end es el arte de lo posible; El pragmatismo es una premisa básica. Creo que la palabra está extremadamente fuera de lugar, ya que se están utilizando elementos adicionales para diseñar en el 99.9% de los sitios web del mundo real (ver elementos del contenedor Bootstrap).
dalgard
12

Una posible solución es usar justify-content: flex-start;en el .gridcontenedor, restricciones de tamaño en sus elementos secundarios y márgenes en los elementos secundarios apropiados , dependiendo del número deseado de columnas.

Para una cuadrícula de 3 columnas, el CSS básico se vería así:

.grid {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
}

.grid > * {
    flex: 0 0 32%;
    margin: 1% 0;
}

.grid > :nth-child(3n-1) {
    margin-left: 2%;
    margin-right: 2%;
}

Es otra solución imperfecta, pero funciona.

http://codepen.io/tuxsudo/pen/VYERQJ

Jared
fuente
11

Sé que hay muchas respuestas aquí, pero ... La forma más simple de hacer esto es con un en gridlugar de flexy grid template columnscon repeaty auto fills, donde debe establecer el número de píxeles que ha dado a cada elemento, 100pxdesde su código de fragmento.

.exposegrid {
     display: grid;
     grid-template-columns: repeat(auto-fill, 100px);
     justify-content: space-between;
}
 .exposetab {
     width: 100px;
     height: 66px;
     background-color: rgba(255, 255, 255, 0.2);
     border: 1px solid rgba(0, 0, 0, 0.4);
     border-radius: 5px;
     box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
     margin-bottom: 10px;
}
<div class="exposegrid">
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
</div>

Surfista de plata
fuente
2
Esta es la solución adecuada para alinear los elementos de la última fila.
a.barbieri
Estoy de acuerdo, la forma correcta es usar la cuadrícula. Se puede lograr con flexbox pero mucho más limpio para usar la cuadrícula.
nbarth
6

Si.! Podemos pero con algunas consultas de medios y el número máximo de columnas están predefinidas .

Aquí estoy usando 4 columnas. Revisa mi código:

.container {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  flex-flow: row wrap;
  -webkit-flex-flow: row wrap;
  -moz-flex-flow: row wrap;
}

.container .item {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  justify-content: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  flex-basis: 25%; //max no of columns in %, 25% = 4 Columns
}

.container .item .item-child {
  width: 130px;
  height: 180px;
  background: red;
  margin: 10px;
}

@media (max-width: 360px) {
  .container .item {
    flex-basis: 100%;
  }
}

@media (min-width:360px) and (max-width: 520px) {
  .container .item {
    flex-basis: 50%;
  }
}

@media (min-width:520px) and (max-width: 680px) {
  .container .item {
    flex-basis: 33.33%;
  }
}
<div class="container">

  <div class="item">
    <div class="item-child">1</div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>

</div>

NOTA
1) No es necesario crear div hijo. Puede ser cualquier otra etiqueta como 'img' r lo que quieras ...
2) Si quieres más columnas, ajusta las consultas de medios y el número máximo de columnas.

Mohamed Mohaideen AH
fuente
Esto crea solo 3 en el último IE
Akxe
6

Si desea una cuadrícula con algo de espacio entre los elementos y los elementos que comienzan sin ningún espacio inicial, entonces esta solución simple funciona:

.grid {
    display: flex;
    flex-flow: row wrap;
    margin: 0 -5px; // remove the inital 5px space
    width: auto;
}
.grid__item {
    width: 25%;
    padding: 0 5px; // should be same as the negative margin above.
}

Si desea el espacio inicial de 5px, simplemente elimine el margen negativo :) Simple.

https://jsfiddle.net/b97ewrno/2/

La respuesta aceptada, aunque es buena, hace que no haya espacio entre los elementos en la segunda fila.

OZZIE
fuente
1
Sorprendido, esto no tiene más votos. Este es un enfoque hermoso que pertenece al museo Flex.
Eduardo La Hoz Miranda
1
@EduardoLaHozMiranda gracias! ¿Pero por qué "museo"? IE11 no es compatible con la cuadrícula CSS y la mayoría de los sitios aún necesitan ser compatibles. + Algunos grandes temporizadores en el desarrollo frontend todavía afirman que hay diferentes casos de uso para grid vs flexbox. Pero tal vez solo quisiste decir que esto debería ser una parte importante del historial web: D
OZZIE
1
LOL sí. Estaba emocionado en ese momento. Solo quería decir que era una excelente y mínima toma de este problema.
Eduardo La Hoz Miranda
@dencey no necesita saber que para esta solución, es un 25%, por lo tanto, un máximo de 4 por fila, pero puede usar el porcentaje que desee
OZZIE
@OZZIE Quiero decir que el ancho del elemento es fijo (como 100px), pero el ancho del contenedor es dinámico, por lo que los elementos por fila son dinámicos.
dencey
4

Si desea alinear el último elemento a la cuadrícula, use el siguiente código:

Contenedor de rejilla

.card-grid {
  box-sizing: border-box;
  max-height: 100%;
  display: flex;
  flex-direction: row;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  justify-content: space-between;
  align-items: stretch;
  align-content: stretch;
  -webkit-box-align: stretch;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-flow: row wrap;
  flex-flow: row wrap;
}

.card-grid:after {
  content: "";
  flex: 1 1 100%;
  max-width: 32%;
}

Artículo en la cuadrícula

.card {
  flex: 1 1 100%;
  box-sizing: border-box;
  -webkit-box-flex: 1;
  max-width: 32%;
  display: block;
  position: relative;

}

El truco consiste en establecer el ancho máximo del elemento igual al ancho máximo de .card-grid: después.

Demostración en vivo en Codepen

Frank Spin
fuente
cthulu te bendice a ti y a tu computadora
L422Y
3
Este enfoque no funciona cuando el tamaño de la tarjeta es fijo y se desconoce el número de tarjetas en cada fila. codepen.io/zendu/pen/WXNGvo
zendu
3

Es posible usar "flex-start" y agregar los márgenes manualmente. Requiere un poco de pirateo matemático, pero definitivamente es fácil de hacer y es fácil de usar con un preprocesador CSS como LESS.

Ver por ejemplo este MENOS mixin:

.flexboxGridMixin(@columnNumber,@spacingPercent) {
  @contentPercent: 100% - @spacingPercent;
  @sideMargin: @spacingPercent/(@columnNumber*2);
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  > * {
    box-sizing: border-box;
    width: @contentPercent/@columnNumber;
    margin-left: @sideMargin;
    margin-right: @sideMargin;
  }
}

Y luego se puede usar fácilmente para mostrar un diseño de cuadrícula sensible:

ul {
  list-style: none;
  padding: 0;
  @spacing: 10%;
  @media only screen and (max-width: 499px) { .flexboxGridMixin(1,@spacing); }
  @media only screen and (min-width: 500px) { .flexboxGridMixin(2,@spacing); }
  @media only screen and (min-width: 700px) { .flexboxGridMixin(3,@spacing); }
  @media only screen and (min-width: 900px) { .flexboxGridMixin(4,@spacing); }
  @media only screen and (min-width: 1100px) { .flexboxGridMixin(5,@spacing); }
}

li {
  background: pink;
  height: 100px;
  margin-top: 20px;
}

Aquí hay un ejemplo de

http://codepen.io/anon/pen/YyLqVB?editors=110

Sebastien Lorber
fuente
Nunca usas @contentPercent. ¿Tenías intención de hacerlo?
neverfox
ancho: @ contentPercent / @ columnNumber;
realtebo
GUAUU ! Estoy realmente impresionado por esta solución. Intentaré adaptarme a mi situación
realtebo
3

Este problema se resolvió para mí usando la cuadrícula CSS,

Esta solución es aplicable solo si tiene un número fijo de columnas, es decir, no. de elementos para mostrar en una sola fila

-> usando la cuadrícula pero sin especificar el número de filas, ya que el número de elementos aumenta, se ajusta en columnas y agrega filas dinámicamente, he especificado tres columnas en este ejemplo

-> no tiene que dar ninguna posición a su hijo / células, ya que lo solucionará, lo que no queremos.

.grid-class{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 80px;
}

Ashwin
fuente
1

Esta versión es la mejor manera para bloques con ancho fijo:

http://codepen.io/7iomka/pen/oxxeNE

En otros casos - versión de dalgard

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
justify-content:center;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  max-width:200px;
  min-width:200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

Znacovean Simion
fuente
0

Hay una forma sin flexbox, aunque deberá cumplir con las siguientes condiciones. 1) El contenedor tiene relleno. 2) Los artículos son del mismo tamaño y sabes exactamente cuántos quieres por línea.

ul {
  padding: 0 3% 0 5%;
}
li {
  display: inline-block; 
  padding: 0 2% 2% 0;
  width: 28.66%;
}

El relleno más pequeño en el lado derecho del contenedor permite el relleno adicional a la derecha de cada elemento de la lista. Suponiendo que otros elementos en el mismo padre que el objeto de la lista están rellenados con 0 5%, quedará al ras con ellos. También puede ajustar los porcentajes a la cantidad de margen que desee o usar calcular valores px.

Por supuesto, puede hacer lo mismo sin el relleno en el contenedor utilizando nth-child (IE 9+) para eliminar el margen en cada tercer cuadro.

ansorensen
fuente
0

Usando flexbox y algunas consultas de medios, hice esta pequeña solución: http://codepen.io/una/pen/yNEGjv (es un poco hacky pero funciona):

.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  max-width: 1200px;
  margin: 0 auto;
}

.item {
  background-color: gray;
  height: 300px;
  flex: 0 30%;
  margin: 10px;

  @media (max-width: 700px) {
     flex: 0 45%;
  }

  @media (max-width: 420px) {
    flex: 0 100%;
  }

  &:nth-child(3n-1) {
    margin-left: 10px;
    margin-right: 10px;
  }
}
Una Kravets
fuente
0

Hice un SCSS mixin para ello.

@mixin last-row-flexbox($num-columns, $width-items){

  $filled-space: $width-items * $num-columns;
  $margin: calc((100% - #{$filled-space}) / (#{$num-columns} - 1));

  $num-cols-1 : $num-columns - 1;

  &:nth-child(#{$num-columns}n+1):nth-last-child(-n+#{$num-cols-1}) ~ & {
    margin-left: $margin;
  }
  @for $i from 1 through $num-columns - 2 { 
    $index: $num-columns - $i;
    &:nth-child(#{$num-columns}n+#{$index}):last-child{
      margin-right: auto;
    }
  }
}

Este es el enlace codepen: http://codepen.io/diana_aceves/pen/KVGNZg

Solo tiene que establecer el ancho de los elementos en porcentaje y número de columnas.

Espero que esto pueda ayudarte.

Diana
fuente
0

Aquí hay otro par de mezclas de scss.

Estos mixins suponen que no va a utilizar complementos js como Isotope (no respetan el orden de marcado html, por lo que se equivocan con las reglas nss de css).

Además, podrá aprovecharlos al máximo, especialmente si está escribiendo sus puntos de respuesta de manera móvil. Lo ideal sería utilizar flexbox_grid () en el punto de interrupción más pequeño y flexbox_cell () en los siguientes puntos de interrupción. flexbox_cell () se encargará de restablecer los márgenes previamente establecidos que ya no se usan en puntos de interrupción más grandes.

Y, por cierto, siempre y cuando configure correctamente las propiedades flexibles de su contenedor, también puede usar solo flexbox_cell () en los elementos, si es necesario.

Aquí está el código:

// apply to the container (for ex. <UL> element)
@mixin flexbox_grid($columns, $gutter_width){

  display: flex;
  flex-direction:row;
  flex-wrap:wrap;
  justify-content: flex-start;

  > *{
    @include flexbox_cell($columns, $gutter_width);
  }
}

// apply to the cell (for ex. a <LI> element)
@mixin flexbox_cell($columns, $gutter_width){
  $base_width: 100 / $columns;
  $gutters: $columns - 1;
  $gutter_offset: $gutter_width * $gutters / $columns;

  flex-grow: 0;
  flex-shrink: 1;
  flex-basis: auto; // IE10 doesn't support calc() here

  box-sizing:border-box; // so you can freely apply borders/paddings to items
  width: calc( #{$base_width}% - #{$gutter_offset} );

  // remove useless margins (for cascading breakponts)
  &:nth-child(#{$columns}n){
    margin-right: 0;
  }

  // apply margin
  @for $i from 0 through ($gutters){
    @if($i != 0){
      &:nth-child(#{$columns}n+#{$i}){
        margin-right: $gutter_width;
      }
    }
  }
}

Uso:

ul{
   // just this:
   @include flexbox_grid(3,20px);
}

// and maybe in following breakpoints, 
// where the container is already setted up, 
// just change only the cells:

li{
   @include flexbox_cell(4,40px);
}

Obviamente, depende de usted eventualmente establecer el relleno / margen / ancho del contenedor y los márgenes inferiores de la celda y similares.

¡Espero eso ayude!

Luca Reghellin
fuente
0

Esto es bastante hacky, pero funciona para mí. Estaba tratando de lograr espacios / márgenes consistentes.

.grid {
  width: 1024px;
  display: flex;
  flex-flow: row wrap;
  padding: 32px;
  background-color: #ddd;  

  &:after {
    content: "";
    flex: auto;
    margin-left:-1%;
  }

  .item {
    flex: 1 0 24.25%;
    max-width: 24.25%;
    margin-bottom: 10px;
    text-align: center;
    background-color: #bbb;

    &:nth-child(4n+2),
    &:nth-child(4n+3),
    &:nth-child(4n+4) {
      margin-left: 1%;
    }

    &:nth-child(4n+1):nth-last-child(-n+4),
      &:nth-child(4n+1):nth-last-child(-n+4) ~ .item {
        margin-bottom: 0;
    }    

  }
}

http://codepen.io/rustydev/pen/f7c8920e0beb0ba9a904da7ebd9970ae/

RustyDev
fuente
0

Parece que nadie propuso la solución de crecimiento flexible en el último artículo. La idea es tener su último elemento flexible para tomar todo el lugar que pueda usando flex-grow: 1.

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid > *:last-child {
  flex-grow: 1;
}

Nota: Esta solución no es perfecta, especialmente si tiene elementos centrados dentro de sus elementos flexibles, ya que se centrará en el último elemento posiblemente enorme.

Dionys
fuente
0

Esta es una combinación de muchas de las respuestas, pero hace exactamente lo que estaba necesitando, es decir, alinear al último niño en un contenedor flexible a la izquierda mientras se mantiene el comportamiento de espacio intermedio (en este caso, es de tres columnas diseño).

Aquí está el marcado:

.flex-container {
  display: flex;
  justify-content: space-between;
  flex-direction: row;
}

.flex-container:after {
  content: "";
  flex-basis: 30%;
}
Margaret
fuente
1
Para ser más genérico: el tamaño de base flexible debe ser igual al tamaño del niño.
Christian Toffolo
1
He encontrado en flex-grow: 0.9lugar de flex-basistrabajos para cualquier cantidad de columnas. Probado en un montón de navegadores modernos: funciona en todos ellos, pero el relleno está roto en IE (pero funciona en Edge0
Patabugen
0

Asumiendo:

  • Desea un diseño de cuadrícula de 4 columnas con ajuste
  • El número de elementos no es necesariamente un múltiplo de 4

Establezca un margen izquierdo en cada elemento, excepto el primer, quinto y noveno elemento, y así sucesivamente. Si el margen izquierdo es de 10 px, entonces cada fila tendrá un margen de 30 px distribuido entre 4 elementos. El ancho porcentual para el artículo se calcula de la siguiente manera:

100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4

Esta es una solución decente para problemas relacionados con la última fila de flexbox.

.flex {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 1em 0 3em;
  background-color: peachpuff;
}

.item {
  margin-left: 10px;
  border: 1px solid;
  padding: 10px;
  width: calc(100% / 4 - 2px - 20px - 10px * (4 - 1) / 4);
  background-color: papayawhip;
}

.item:nth-child(4n + 1) {
  margin-left: 0;
}

.item:nth-child(n + 5) {
  margin-top: 10px;
}
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
</div>

Salman A
fuente
0

Si conoce el ancho de los espacios entre los elementos en la fila y la cantidad de elementos en una fila, esto funcionaría:

Ejemplo: 3 elementos en una fila, espacio de 10 píxeles entre elementos

div:last-child:nth-child(3n+2) {
  flex-grow: 1
  margin-left: 10px
}
norweny
fuente
0

Simplemente use el truco Jquery / Javascript para agregar un div vacío:

if($('.exposegrid').length%3==2){
 $(".exposegrid").append('<div class="exposetab"></div>');
}
Waheed Mazhar
fuente
-1

Oh chico, creo que encontré una buena solución con CSS mínimo y sin JS. Echale un vistazo:

img {width:100%;}
li {
  display: inline-block;
  width:8em;
  list-style:none;
}
ul {text-align: justify;}
<ul>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

¡La clave aquí es recordar que lo que estamos tratando de lograr es exactamente lo que text-align: justifyhace!

Los elementos vacíos en el HTML están ahí para que la última fila se muestre perfectamente sin cambiar la apariencia, pero puede que no sea necesario dado lo que está tratando de lograr. Para un equilibrio perfecto en cada situación, necesita al menos x-4 elementos vacíos, x es el número de elementos para mostrar, o n-2, n es el número de columna que desea mostrar.

Sharcoux
fuente
-1

Simplemente agregue algunos elementos falsos con las mismas propiedades, excepto la altura establecida en 0px hasta el final.

Erik Parso
fuente
Agregar artículos falsos es una mala práctica en todos los sentidos. Se supone que no debe llenar el DOM con cosas solo para hackear css a menos que sea obligatorio. Por muchas razones, desde la accesibilidad, hasta inundar la base de código con cosas extrañas, hasta hacer que la lógica sea más compleja de entender y la lista continúa. No recomiende hacks a menos que explícitamente diga que podría ser una mala solución o que hay un caso especial para eso.
Eksapsy
-4

quieres alinear

usar en align-content: flex-start;lugar dejustify-content: space-between;

esto tira los elementos de la última fila hacia la izquierda y también distribuye el espacio de manera uniforme,

.container {
  display: flex;
  flex-flow: row wrap;
  align-content: flex-start;
  /*justify-content: space-between; remove this line!!!! */ 
}

https://codepen.io/anon/pen/aQggBW?editors=1100


¡La solución de danAnderson NO ES DINÁMICA. PERIODO!

cuando el ancho del elemento cambió de 25 a 28, dan anderson falla el espacio entre imágenes

danAnderson: https://codepen.io/anon/pen/ZwYPmB?editors=1100

dinámico: https://codepen.io/anon/pen/aQggBW?editors=1100

Eso es lo que he estado tratando de decir. dans es hacky .....

bh_earth0
fuente
-7

Pude hacerlo justify-content: space-betweenen el contenedor

chovy
fuente