1

I have a simple grid here using css flex.

I need the 3 columns that are a percentage of the parent container width.

I also need a right margin on each block.

I nearly have it working here but I need the blocks in the second line to go from left to right, here the second block on the second row is on the right.

.block {
  border: 1px solid lightgrey;
  display: flex;
  flex-wrap: wrap;
  padding: 5px;
  max-width: 900px;
  justify-content: space-between;
  //justify-content: flex-start;

}

.block__item {
  //align-self: flex-start;
  background: grey;
  height: 20px;
  //margin-right: 8px;
  margin-bottom: 2px;
  width: calc(33.3% - 2px);
}
<div class="block">
  <div class="block__item"></div>
  <div class="block__item"></div>
  <div class="block__item"></div>
  <div class="block__item"></div>
  <div class="block__item"></div>
</div>
ttmt
  • 5,822
  • 27
  • 106
  • 158

3 Answers3

1

You were on the right track originally with using justify-content: flex-start. It was justify-content: space-between that was giving you the gap on the second row, so I removed that and everything lined up. I adjusted the margins and padding too to match the spacing.

.block {
  border: 1px solid lightgrey;
  display: flex;
  flex-wrap: wrap;
  padding: 5px 3px 5px 5px;
  max-width: 900px;
  justify-content: flex-start;

}

.block__item {
  background: grey;
  height: 20px;
  margin-bottom: 2px;
  width: calc(33.3% - 2px);
  margin-right:2px;
}
<div class="block">
  <div class="block__item"></div>
  <div class="block__item"></div>
  <div class="block__item"></div>
  <div class="block__item"></div>
  <div class="block__item"></div>
</div>
jleggio
  • 1,266
  • 1
  • 9
  • 16
1

Another way to think about it is to use a wrapping element (.block__item) that provides the spacing between elements with internal padding. These wrapping elements are physically next to each other but provide the visual distinction between their contents (.block__content).

The benefit of this is that you don't need to include the spacing in your calculations for width or flex-basis. If you want to change the spacing, simply update padding.

*Note that you need to change the box-model of your elements to border-box to take advantage of this.

* {
  box-sizing: border-box;
}

.block {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  max-width: 900px;
  border: 1px solid lightgrey;
  padding: 2px;
}

.block__item {
  flex: 0 1 calc(100% / 3);
  padding: 2px;
}

.block__content {
  height: 20px;
  background-color: grey;
  color: white;
  font-size: 10px;
  font-weight: 700;
  line-height: 20px;
  text-align: center;
}

@media (max-width: 400px) {
  .block__item {
    flex-basis: 50%;
  }
}
<div class="block">
  <div class="block__item">
    <div class="block__content">1</div>
  </div>
  <div class="block__item">
    <div class="block__content">2</div>
  </div>
  <div class="block__item">
    <div class="block__content">3</div>
  </div>
  <div class="block__item">
    <div class="block__content">4</div>
  </div>
  <div class="block__item">
    <div class="block__content">5</div>
  </div>
</div>
chazsolo
  • 7,873
  • 1
  • 20
  • 44
0

You could reduce the margins a bit so they fit better and keep aligning flex items to the left with justify-content: flex-start; or you could also use CSS Grid instead and define the gap you need as well as the total columns you need (3 in this case), with grid you can even avoid percentage calculations and just tell each item to use a fraction of the available space.

The biggest benefit of CSS Grid I think would be that you avoid wasting space that might be left out with percentages, and also you don't need to change anything else on the items if you want to add or remove columns.

.block {
  border: 1px solid lightgrey;
  display: flex;
  flex-wrap: wrap;
  padding: 5px;
  max-width: 900px;
  justify-content: flex-start;

}

.block__item {
  background: grey;
  height: 20px;
  margin-right: 2px;
  margin-bottom: 2px;
  width: calc(33.3% - 2px);
}

.block-grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(20px, auto);
  grid-gap: 2px;
  border: 1px solid grey;
  padding: 5px;
}

.block-grid__item{
  background-color: red;
}
<div class="block">
  <div class="block__item"></div>
  <div class="block__item"></div>
  <div class="block__item"></div>
  <div class="block__item"></div>
  <div class="block__item"></div>
</div>

<div class="block-grid">
  <div class="block-grid__item"></div>
  <div class="block-grid__item"></div>
  <div class="block-grid__item"></div>
  <div class="block-grid__item"></div>
  <div class="block-grid__item"></div>
</div>
IvanS95
  • 5,364
  • 4
  • 24
  • 62