11

I have a div and I have 12 items aligned at center using flex.

But I just want to have 4 items in row, so I want 3 rows of 4 columns.

This is ok to do with flex? And do you know how to do?

I'm trying to do that like this: https://jsfiddle.net/18mzsqcx/1/, but it's not working.

Or it's better to just create a div for example .col4 with width equal to 25% and some margins and put this class .col4 in each item?

*,
*:after,
*:before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}

.container {
  float: left;
  width: 100%;
  background-color: red;
}

.content {
  width: 94%;
  margin: 0px auto;
  background-color: yellow;
  padding: 30px;
}

.categories {
  display: flex;
  justify-content: space-between;
  background-color: blue;
}

.categories_item a {
  color: green;
}

.categories_item {
  flex-grow: 1;
}
<div class="container">
  <div class="div content">


    <div class="categories">
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>

      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>

      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>

      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>

      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>

      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>

      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>

      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>

      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>

      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>

      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>

    </div>
  </div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Possible duplicate of [How to force a flex box to display 4 items per row](https://stackoverflow.com/questions/29546550/how-to-force-a-flex-box-to-display-4-items-per-row) – aaronb Jul 28 '17 at 17:57

3 Answers3

12

By default, a flex container is set to flex-wrap: nowrap. This means that flex items will not be able to wrap to new lines.

So the first thing you should do is add flex-wrap: wrap to your container.

.categories {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;  /* NEW */
}

Then, define your flex items so that only four can fit on a row.

Instead of this:

.categories_item { flex-grow: 1; }

Try this:

.categories_item { flex: 1 0 20%; margin: 5px; }

revised demo

*,
*:after,
*:before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  float: left;
  width: 100%;
  background-color: red;
}

.content {
  width: 94%;
  margin: 0px auto;
  background-color: yellow;
  padding: 30px;
}

.categories {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;                /* NEW */
}

.categories_item a {
  color: white;
}

.categories_item {
  flex: 1 0 20%;                 /* NEW */
  margin: 5px;                   /* NEW */
  background-color: blue;
}
<div class="container">
  <div class="div content">
    <div class="categories">
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
      <div class="categories_item">
        <a href="" class="">
          <span>Item</span>
        </a>
      </div>
    </div>
  </div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Thanks for your answer, it works. So using this approach is not necessary using grids right? –  Jul 28 '17 at 19:58
  • 1
    In this case, since you know the size of each flex item, you don't need to use CSS Grid. Flexbox can handle this well. – Michael Benjamin Jul 28 '17 at 20:00
  • Thanks again. Yes but for example in css grid we also know the size of each item, that is, at least we know the percentage that we want to have. So Im not understanding well why the grids are really necessary. –  Jul 28 '17 at 20:12
  • Here's an explanation that may help you: https://stackoverflow.com/q/44377343/3597276 – Michael Benjamin Jul 28 '17 at 20:16
  • Easy to miss. Great answer, also the `flex-grow` replacement is nice. Thanks! – Jeff Huijsmans Nov 05 '18 at 13:58
3

This will do the trick, keep three elements in one div, so there will be 4 divs for 12 items

.container {
  float: left;
  width: 100%;
  background-color: red;
}

.content {
  width: 94%;
  margin: 0px auto;
  background-color: yellow;
  padding: 30px;
}

.categories {
  display: flex;
  justify-content: space-between;
  background-color: blue;
}

.categories_item a {
  color: green;
}

.categories_item {
  flex-grow: 1;
}
<div class="container">
  <div class="div content">


    <div class="categories">
      <div id="row">

        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>

        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>

        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>


        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>
      </div>
      <div id="row">
        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>

        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>


        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>
        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>
      </div>
      <div id="row">
        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>

        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>

        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>

        <div class="categories_item">
          <a href="" class="">
            <span>Item</span>
          </a>
        </div>
      </div>

    </div>
  </div>
</div>
siawo
  • 246
  • 2
  • 9
0

Flex-grid makes life very simple for the grid.

HTML

<div class="flex-grid">
  <div class="flex-col"></div>
  <div class="flex-col"></div>
  <div class="flex-col"></div>
  <div class="flex-col"></div>
</div>

CSS

.flex-grid {
  display: flex;
}
.flex-col {
  flex: 1;
}

https://jsfiddle.net/wh03p4s5/

RGriffiths
  • 5,722
  • 18
  • 72
  • 120