Artículos flexibles de igual ancho incluso después de envolverlos

Resuelto Adam Szmyd asked hace 7 años • 2 respuestas

¿Es posible crear una solución CSS pura como esta?

  1. Los artículos tienen algunos min-width.
  2. Deberían crecer dinámicamente para llenar todo el ancho del contenedor y luego ajustarse a nuevas líneas.
  3. Todos los elementos de la lista deben tener el mismo ancho.

Asi es como luce ahora:

ingrese la descripción de la imagen aquí

Y así es como me gustaría que se viera también (he administrado el ancho de los elementos inferiores manualmente solo para mostrar el resultado esperado):

ingrese la descripción de la imagen aquí

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

.item {
  background: yellow;
  min-width: 100px;
  height: 20px;
  text-align: center;
  border: 1px solid red;
  flex-grow: 1;
}
<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 class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>
Expandir fragmento

Aquí hay una demostración de violín .

Adam Szmyd avatar May 24 '17 16:05 Adam Szmyd
Aceptado

Actualmente, flexbox no ofrece una solución limpia para alinear elementos flexibles en la última fila o columna. Está más allá del alcance de la especificación actual.

Aquí hay más información y varias soluciones que la gente ha utilizado para solucionar el problema:

  • Dimensionar elementos flexibles en la última fila
  • ¿Es posible que los elementos flexibles se alineen firmemente con los elementos que están encima de ellos?

Sin embargo, la alineación de la última fila no es un problema con otra tecnología CSS3, Grid Layout . De hecho, este método es muy sencillo (y no requiere cambios en el HTML):

.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  grid-auto-rows: 20px;
  grid-gap: 5px;
}

.item {
  background: yellow;
  text-align: center;
  border: 1px solid red;
}
<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 class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>
Expandir fragmento

Demostración de jsFiddle

La grid-template-columnspropiedad establece el ancho de las columnas definidas explícitamente. La regla anterior le dice al contenedor de la cuadrícula que cree tantas columnas como sea posible ( auto-fit), y el ancho de cada columna será un mínimo de 100 px y un máximo de 1fr, lo que consume el espacio restante (similar a flex-grow: 1). Cuando no hay más espacio en la fila, se crea una nueva fila.

La grid-auto-rowspropiedad establece la altura de las filas creadas automáticamente. En esta cuadrícula, cada fila tiene 20 píxeles de alto.

La grid-gappropiedad es una abreviatura de grid-column-gapy grid-row-gap. Esta regla establece un espacio de 10 píxeles entre los elementos de la cuadrícula. No se aplica al área entre los artículos y el contenedor.

Tenga en cuenta que todas las configuraciones anteriores están a nivel de contenedor. A diferencia de los elementos flexibles, podemos eliminar las responsabilidades de altura, ancho y margen (hasta cierto punto) de los elementos de la cuadrícula.

Michael Benjamin avatar May 24 '2017 12:05 Michael Benjamin

En este momento, no existe una solución CSS pura. Flexbox siempre intenta llenar todo el ancho del contenedor con elementos cultivables. Por lo tanto, deberá insertar algunos elementos ocultos que llenarán el espacio vacío y serán invisibles para el usuario.

Prueba esto:

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

.item {
  background: yellow;
  min-width: 100px;
  height: 20px;
  text-align: center;
  border: 1px solid red;
  flex-grow: 1;
}

.item-hidden {
  min-width: 100px;
  flex-grow: 1;
  border: 1px solid transparent;
}
<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 class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
  <div class="item-hidden"></div>
  <div class="item-hidden"></div>
  <div class="item-hidden"></div>
  <div class="item-hidden"></div>
</div>
Expandir fragmento

Aquí se discutió un problema similar: Flex-box: alinear la última fila con la cuadrícula

En el futuro, podrá utilizar varios pseudoelementos ::after, por lo que no necesitará insertar elementos adicionales en HTML.

Ondra Koupil avatar May 24 '2017 09:05 Ondra Koupil