cssflexbox

4 items per row but with empty space if there is less than 4 items?


I want to know if there is a way to have 4 items per row but not have the rows with <4 items to stretch to fill the space.

.item-container {
  display: inline-flex;
  flex-wrap: wrap;
  flex-direction: row;
}

.item {
  display: flex;
  flex: 1 0 calc(25% - 40px);
  color: black;
  background-color: rgba(250, 250, 210);
  flex-direction: column;
  padding: 10px;
  margin: 10px;
  border-radius: 20px;
}
/* If there are 4 items it works well, but if there is 1-3 items they stretch to fill the space and look off. */

Solution

  • A grid layout is great for this.

    The following property:
    grid-template-columns: repeat( auto-fill, minmax(calc(25% - 40px), 1fr) )

    Creates a new column, as long as it can fit in the layout. The minimum size of the column must be the first value specificed in minmax(), and the maximum value is 1fr, which just equates to 1 column.

    IMHO, another value than calc(25% - 40px) should be used, as it is now calculating that value relative to the column. You can use gap instead to create gap between items.

    /* demo purpose */
    body {
      display: flex;
      flex-direction: column;
    }
    
    .item-container {
      display: grid;
      grid-template-columns: repeat( auto-fill, minmax(25%, 1fr) );
      max-width: 600px;
    }
    
    .item {
      display: flex;
      color: black;
      background-color: rgba(250, 250, 210);
      flex-direction: column;
      padding: 10px;
      margin: 10px;
      border-radius: 20px;
    }
    <div class="item-container">
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
    </div>
    
    <div class="item-container">
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
    </div>
    
    <div class="item-container">
      <div class="item"></div>
      <div class="item"></div>
    </div>
    
    <div class="item-container">
      <div class="item"></div>
    </div>