Flex-box: Alinea la última fila a la grilla

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 artículos en la última fila estén alineados con el otro. justify-content: space-between; se debe usar porque se puede ajustar el ancho y la altura de la cuadrícula.

Actualmente parece

El artículo en la parte inferior derecha debe estar en el medio

Aquí, quiero que el artículo en la parte inferior derecha esté en la “columna del medio”. ¿Cuál es la forma más simple de lograr eso? Aquí hay un jsfiddle pequeño que muestra este comportamiento.

Agregar un :after que se autocompleta el espacio. No es necesario que contamine 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; } 

Una técnica sería insertar una cantidad de elementos adicionales (tantos como la cantidad máxima de elementos que esperas tener en una fila) que tengan una altura cero. El espacio aún está dividido, pero las filas superfluas colapsan en la 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; } 
 
  • a
  • b
  • c
  • d
  • e
  • f
  • g
  • h
  • i
  • j
  • k

Como han mencionado otros carteles, no hay una forma clara de alinear la última fila con flexbox (al menos según la especificación actual)

Sin embargo, por 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) Hacer que el contenedor sea un contenedor de red

2) Configure la grilla con columnas automáticas de ancho 100px. (Tenga en cuenta el uso de autocompletar (como apposed para auto-fit , que (para un diseño de 1 fila) colapsa las pistas vacías a 0, lo que hace que los elementos se expandan para ocupar el espacio restante. Esto daría como resultado un ‘justificado’ espacio-entre ‘diseño cuando la cuadrícula tiene una sola fila que en nuestro caso no es lo que queremos. (echa un vistazo a esta demostración para ver la diferencia entre ellos)).

3) Establecer espacios vacíos / canaletas para las filas y columnas de la cuadrícula; aquí, dado que se desea un diseño de ‘espacio entre’, la brecha en realidad será un espacio mínimo porque crecerá según sea necesario.

4) Similar a flexbox.

 ul { display: grid; grid-template-columns: repeat(auto-fill, 100px); grid-gap: 1rem; justify-content: space-between; /* boring properties */ list-style: none; background: wheat; padding: 2rem; width: 80vw; margin: 0 auto; } li { height: 50px; border: 1px solid green; } 
 

Sin ningún margen adicional, simplemente agregué ::after funcionó 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 así:

 

No puedes. Flexbox no es un sistema de grillas. No tiene los constructos de lenguaje para hacer lo que estás pidiendo, al menos no si estás 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 tiene un mejor soporte y no requiere establecer una altura específica:

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

 ul { columns: 15em; } 

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

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

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 grilla

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

El truco es establecer el ancho máximo del artículo igual al ancho máximo de .card-grid: after.

Demostración en vivo en Codepen

Es posible usar “inicio flexible” y agregar los márgenes manualmente. Requiere algo de hackeo matemático pero es definitivamente fácil de hacer y hace que sea fácil de usar con un preprocesador CSS como LESS.

Ver por ejemplo esta mezcla MENOS:

 .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 puede usarse 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

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 espacio entre comportamiento (en este caso es una columna de tres) diseño).

Aquí está el marcado:

 .flex-container { display: flex; justify-content: space-between; flex-direction: row; } .flex-container:after { content: ""; flex-basis: 30%; } 

Sí.! Podemos pero con algunas consultas de medios y máximo de columnas predefinidas .

Aquí estoy usando 4 columnas. Verifique 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%; } } 
 
1

Puede lograr esto simplemente con flex-start y max-width.

https://codepen.io/moladukes/pen/NvzBrQ

 .container { display: flex; justify-content: flex-start; flex-flow: row wrap; } .item { width: 130px; max-width: 130px; height: 180px; background: red; margin: 20px; } 

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; } 
 
  • a
  • b
  • c
  • d
  • e
  • f
  • g
  • h
  • i
  • j
  • k

Parece que nadie propuso la solución flex-grow en el último artículo. La idea es tener su último artículo 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 elemento posiblemente más grande de flexión.

Hay una forma sin flexbox, aunque necesitarías cumplir con las siguientes condiciones. 1) El contenedor tiene relleno. 2) Los artículos son del mismo tamaño y usted sabe exactamente cuántos quiere 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 extra a la derecha de cada elemento de la lista. Suponiendo que otros elementos en el mismo elemento primario que el objeto de la lista se rellenan con 0 5%, estarán alineados con ellos. También puede ajustar los porcentajes con el margen que desee o usar calcular los valores de 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.

Usando flexbox y algunas consultas de medios, hice este pequeño trabajo: http://codepen.io/una/pen/yNEGjv (es un poco raro 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; } } 

Hice una mezcla de SCSS para eso.

 @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 del 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.

Aquí hay otro par de scss mixins.

Estos mixins asumen que no vas a usar complementos js como Isótopos (no respetan el orden de marcado html, por lo que se equivocan con las reglas n. ° s).

Además, podrá aprovecharlos al máximo, especialmente si está escribiendo sus puntos de interrupción receptivos de manera móvil. Lo ideal sería utilizar flexbox_grid () en el punto de corte 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 que configure correctamente las propiedades flexibles de su contenedor, también puede usar solo flexbox_cell () en los artículos, si es necesario.

Aquí está el código:

 // apply to the container (for ex. 
    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
  • 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!

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/

Si el ancho de los elementos secundarios es variable (lo que da como resultado una cantidad variable de elementos secundarios por fila), no hay forma de hacerlo con CSS solo. Así que recurrí a JavaScript para:

  • agregue un elemento .sizer como último elemento secundario, inicialmente con flex-basis:100%
  • reduzca gradualmente su flex-basis hasta que “salte” en la fila anterior (o llegue a flex-basis:0% )
  • cuando sucede lo anterior, empuja todos los elementos en la última fila al comienzo de la fila: ¡trabajo hecho!

Trabajo, ejemplo genérico:

 // first part of the script generates cards with random words, ignore it let words = [ 'interesting', 'tongue', 'excellent', 'start', 'sticky', 'lame', 'lopsided', 'ill-informed', 'terrible', 'reduce', 'near', 'order' ] for (var i = 0; i < 20; i++) { let text = ''; for (var j = 0; j < 3; j++) { text += words[parseInt(Math.random() * words.length)] + ' ' } $('.container').append($('
', { class: 'card', text: text })) } // the juice starts here: $('.container').append( $('
', { class:'sizer' })); let topSizer = $('.sizer')[0].getBoundingClientRect().top, perCent = 100; while ( $('.sizer')[0].getBoundingClientRect().top === topSizer && topSizer > 0 ) { $('.sizer').css({flexBasis:(perCent--)+'%'}); }
 .container { display: flex; flex-flow: row wrap; align-content: flex-start; } .card { flex: 1 1 0; padding: .8rem; border: 1px solid #ccc; margin: 0 -1px -1px 0; } .sizer { flex-basis: 100%; } 
  

Si quiere una grilla con algo de espacio entre los ítems y los ítems que comienzan sin espacio inicial, entonces esta simple solución 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 5 píxeles, simplemente elimine el margen negativo 🙂 Simple.

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

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

Asumiendo:

  • Desea un diseño de cuadrícula de 4 columnas con envoltura
  • La cantidad de artículos no es necesariamente un múltiplo de 4

Establezca un margen izquierdo en cada elemento excepto 1.er, 5. ° y 9. ° elemento y así sucesivamente. Si el margen izquierdo es 10px, cada fila tendrá un margen de 30px 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 los problemas relacionados con la última fila de flexbox.

 .flex { display: flex; flex-direction: row; flex-wrap: wrap; margin: 1em 0; background-color: peachpuff; } .item { margin-left: 10px; border: 1px solid; padding: 10px; width: calc(100% / 4 - 22px - 2px - 10px * (4 - 1) / 4); background-color: papayawhip; } .item:nth-child(4n + 1) { margin-left: 0; } .item:nth-child(n + 5) { margin-top: 10px; } 
 
1
2
3
4
1
2
3
4
5
6
1
2
3
4
5
6
7
8
9

Pude hacerlo con justify-content: space-between en el contenedor