CSS - Flex elements with margin right

Viewed 5725

I want to create a grid of blocks using css flex.

The blocks need to be in three columns and they should be a 3rd of the width of the parent container.

My problem is I need a right margin on the blocks.

The blocks need to be a percentage of the container so I cant use space between.

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

.block__item {
  background: grey;
  height: 20px;
  margin-right: 2px;
  //margin-bottom: 2px;
  width: 33.33%;
}

.block__item:nth-child(3n){
  margin-right: 0;
}
<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>

5 Answers

A bit late to the party, but I found a working hack:

Have the overflow auto on a container element around it and give the element itself an invisible border of 8px on the side(s) where you expect the scrollbar to appear. When the scrollbar does show, it will be displayed on top of the invisible border instead of on top of the content.

Judging by your question, I believe this is what you are trying to accomplish:

  .block {
  border: 1px solid lightgrey;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  padding: 5px;
  max-width: 900px;
  -webkit-justify-content: space-between;
  -ms-flex-pack: justify;
   justify-content: space-between;
}

.block__item {
  background: grey;
  height: 20px;
  margin-right: 2px;
  margin-bottom: 2px;
  width: 33%;
}

<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 class="block__item"></div>
      <div class="block__item"></div>
      <div class="block__item"></div>
      <div class="block__item"></div>
    </div>

I added the vendor prefixes so that it displays consistently across all browsers. You can adjust the spacing between boxes by adjusting the percentage (i.e. 31% width). If you plan on using Flexbox often you should check out this site for quick vendor versions: http://the-echoplex.net/flexyboxes/

Maybe you can simply decrease the width of the blocks, and the rest of the witdh assign it to the margin.

Like this:

.block__item {
    background: grey;
    height: 20px;
    margin-right: 3%;
    width: 30%;
}

The problem is the padding on the container. But you can use width: calc((100% - 10px) / 3); to calculate the correct 33,33% of the container width excluding the padding.

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

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

.block__item:nth-child(3n){
  margin-right: 0;
}
<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>

Very Good Question

.block {
  border: 1px solid lightgrey;
  display: flex;
  flex-wrap: wrap;
  max-width: 900px;
  margin-left: -1px;
  margin-right: -1px;
}

.block__item {
  background: grey;
  background-clip: content-box;
  height: 20px;
  flex-basis: 33.33%;
  box-sizing: border-box;
  padding-left: 1px;
  padding-right: 1px;
  margin-bottom: 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>

Actually, it's good practice to split layout and content in html.

.b-row {
  display: flex;
  flex-wrap: wrap;
  margin-left: -1px;
  margin-right: -1px;
}
.b-row > .b-col {
  flex-basis: 33.33%;
  box-sizing: border-box;
  padding-left: 1px;
  padding-right: 1px;
  margin-bottom: 2px;
}

.block__item {
  background-color: grey;
  height: 20px;
}
<div class="block">
  <div class="b-row">
    <div class="b-col">
      <div class="block__item">asdfasfasdf</div>
    </div>
    <div class="b-col">
      <div class="block__item">asdfasfdasf</div>
    </div>
    <div class="b-col">
      <div class="block__item">asdfasdfas</div>
    </div>
    <div class="b-col">
      <div class="block__item">asdfasdfa</div>
    </div>
    <div class="b-col">
      <div class="block__item">asdfasdfadsf</div>
    </div>
  </div>
</div>

Anyway, you can choose your preference.

Related