Dimensionamiento de elementos flexibles en la última fila

7 minutos de lectura

Avatar de usuario de Baro
baro

Mi problema es que quiero el flexbox con ancho de rango variable, y todo funciona bien, pero no en la última fila. Quiero la misma dimensión para todos los niños, incluso cuando la fila no está llena de niños (la última fila).

#products-list {
    position:relative;
    display: flex;
    flex-flow: row wrap;
    width:100%;
}

#products-list .product {
    min-width:150px;
    max-width:250px;
    margin:10px 10px 20px 10px;
    flex:1;
}

yo creé una situación dinámica en jsviolín

Mis divs flexibles pueden encogerse hasta 150 px y crecer hasta 250 px, pero todos deben tener el mismo tamaño (y obviamente quiero una solución CSS, con JS conozco el camino).

Avatar de usuario de Michael Benjamin
miguel benjamin

Desafortunadamente, en la iteración actual de flexbox (Nivel 1), no hay una forma clara de resolver el problema de alineación de la última fila. Es un problema común.

Sería útil tener una propiedad flex en la línea de:

  • last-row
  • last-column
  • only-child-in-a-row
  • alone-in-a-column

Este problema parece ser de alta prioridad para Flexbox Nivel 2:

Aunque este comportamiento es difícil de lograr en flexbox, es simple y fácil en Diseño de cuadrícula CSS:

  • Artículos flexibles de igual ancho incluso después de que se envuelven

En caso de que Grid no sea una opción, aquí hay una lista de preguntas similares que contienen varios hacks de flexbox:

  • Dimensionar y alinear correctamente los elementos flexibles en la última fila
  • Flex-box: alinear la última fila con la cuadrícula
  • Envoltura Flexbox: alineación diferente para la última fila
  • ¿Cómo puede un elemento flexible mantener las mismas dimensiones cuando se fuerza a una nueva fila?
  • ¿Selector para un elemento solo en una fila?
  • Alineación de elementos en la última fila de flexbox
  • ¿Cómo puedo permitir que los artículos flexibles crezcan manteniendo el mismo tamaño?
  • Alinear a la izquierda la última fila de flexbox usando espacios entre y márgenes
  • Margen inconsistente entre elementos flexibles en la última fila
  • ¿Cómo mantener los elementos flexibles envueltos del mismo ancho que los elementos de la fila anterior?
  • Cómo alinear la última fila / línea a la izquierda en flexbox de varias líneas
  • Los últimos hijos de la cuadrícula obtienen una canaleta gigante debido al espacio intermedio de flexbox
  • Gestión de justificar contenido: espacio entre en la última fila
  • Espacio Flexbox entre comportamiento combinado con envoltura.
  • ¿Es posible usar CSS Flexbox para estirar elementos en cada fila manteniendo anchos consistentes?
  • Evite que el último artículo se estire para llenar el contenedor

  • Esta respuesta tiene el mismo problema que los libros en estos días: demasiada información => nadie la lee. Hubiera sido bueno tener un TL;DR; sección (solución rápida).

    – tao

    28 de abril de 2017 a las 10:05

  • @AndreiGheorghiu, no conozco una solución rápida para este problema. De hecho, el problema en sí varía en naturaleza. Si tiene una solución universal, debe publicar una respuesta.

    – Michael Benjamín

    28 de abril de 2017 a las 12:09


  • Además, para alguien que lee esta respuesta únicamente con fines educativos, creo que tiene razón. Pocas personas, si es que alguna, revisarán la lista completa de enlaces.

    – Michael Benjamín

    28 de abril de 2017 a las 12:10

  • Pero para alguien que visita esta página que necesita desesperadamente una solución, diría que revisarán todos y cada uno de los enlaces con la esperanza de encontrar un método que funcione. Basado en los votos a favor de esta respuesta, y Éste y Éste (ver “Nota al margen” en la parte inferior), diría que al menos algunas personas encuentran útiles las referencias.

    – Michael Benjamín

    28 de abril de 2017 a las 12:11


  • @Michael_B, no tuve la paciencia para revisar todos los enlaces y verificar si a alguien se le ocurrió una solución js, así que hice la mía, para el caso especial en el que no hay una cuadrícula determinada (o ancho de niño conocido) . Solo niños de ancho variable, la última fila debe alinearse a la izquierda, mientras que las filas anteriores deben estirarse para llenar el tamaño completo.

    – tao

    28 de junio de 2017 a las 14:59


Avatar de usuario de Boris D. Teoharov
Boris D. Teoharov

Como una solución rápida y sucia se puede utilizar:

.my-flex-child:last-child/*.product:last-child*/ {
  flex-grow: 100;/*Or any number big enough*/
}

  • ¿No debería ser así? flex-grow: 0? OP quiere “la misma dimensión para todos los niños, incluso cuando la fila no está llena de niños”. flex-grow: 100 potencialmente haría que el elemento llenara el ancho de su padre.

    – FullStackChris

    22 de abril de 2020 a las 10:40

  • Incluso si flex-grow: 0, esto aún causaría que el penúltimo elemento crezca para tomar ese ancho.

    – Matt Eland

    8 de julio de 2020 a las 21:33

Puede intentar usar grid en lugar de flexbox aquí:

#products-list {

  display: grid;
  grid-gap: 5px;
  grid-template-columns: repeat(auto-fit, minmax(100px, 250px)); //grid automagic
  justify-content: start; //start left

}

Enlace de violín

Avatar de usuario de David
David

Si todas sus filas tienen la misma cantidad de elementos, puede usar :nth-last-child. Por ejemplo, si todas las filas tienen 3 elementos, puede hacer algo como esto para eliminar el margen de los últimos 3 elementos:

.container{
  display: flex;
  flex-wrap: wrap;
  background: yellow;
}

.item{
  width: calc((100% - 2*10px)/3);
  height: 50px;
  background: blue;
  color: white;
  margin-right: 10px;
  margin-bottom: 10px;
  padding: 5px;
  box-sizing: border-box;
}

/* last item of each row */
.item:nth-child(3n){
  margin-right: 0;
  font-size: 150%;
}

/* last 3 items */
.item:nth-last-child(-n+3){
  margin-bottom: 0;
  background: green;
}
<div class="container">
  <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>

Avatar de usuario de Fanky
extravagante

Un truco simple agrega un espacio flexible para llenar el resto de la última fila:

#products-list{
    display:flex;
    flex-flow: row wrap;
    justify-content:space-between;
}
#products-list::after {
    content: "";
    flex: auto;
    flex-basis: 200px;/*your item width*/
    flex-grow: 0;
}

Pero entonces no debe usar márgenes en los elementos. Más bien envuélvalos en recipientes con relleno.

Avatar de usuario de TylerH
tylerh

Usé esta solución alternativa, incluso si no es muy elegante y no usa el poder de Flexbox.

Puede llevarse a cabo en las siguientes condiciones:

  • Todos los artículos tienen el mismo ancho.
  • Los artículos tienen un ancho fijo.
  • Tu usas SCSS/SASS (aunque se puede evitar)

Si este es el caso, puede usar el siguiente fragmento:

 $itemWidth: 400px;
 $itemMargin: 10px;

html, body {
  margin: 0;
  padding: 0;
}

.flex-container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 0 auto;
  border: solid 1px blue;
}

@for $i from 1 through 10 {
  @media only screen and (min-width: $i * $itemWidth + 2 * $i * $itemMargin) {
    .flex-container {
      width: $i * $itemWidth + 2 * $i * $itemMargin;
    }
  }
}

.item {
  flex: 0 0 $itemWidth;
  height: 100px;
  margin: $itemMargin;
  background: red;
}
<div class="flex-container">
  <div class="item"></div>
  <div class="item" style="flex: 500 0 200px"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Aquí He creado un ejemplo en códec que también implementa margin.

La segunda y la tercera condición se pueden evitar respectivamente utilizando variables css (si decidió proporcionar soporte para ello) y compilando el fragmento scss anterior.

Bueno, es cierto, podríamos hacerlo también antes de flexbox, pero display: flex puede ser aún esencial para un diseño receptivo.

avatar de usuario de simi
simi

Hay una gran solución que funciona siempre. agregue un div con producto de clase (la misma clase para otros elementos que están bajo flexibilidad) y agregue un estilo para este div: altura: 0px; debe agregar tantas inmersiones como sea posible en una fila.

<div class="product" style="height:0px">

tantos como pueda haber en una fila. Eso es todo. Funciona siempre.

  • Yo diría que es más un truco que una gran solución, especialmente en situaciones en las que no sabes el conteo por adelantado.

    – crollywood

    11 oct 2021 a las 11:47

  • ¡Es una gran solución, porque si no sabe el conteo por adelantado y quiere que la última fila sea siempre! perfecto, entonces es una forma muy sencilla. trabajo genial siempre. funciona en todos los tamaños. Nada puede ser mejor que esta solución.

    – simi

    12 oct 2021 a las 13:48

¿Ha sido útil esta solución?