3

I have a dynamic list of items (containing text) placed column-wise which I need to break after every 5th item.

Dynamic FlexBox multi-column

I have only 2 constraints:

  1. Width of each Item is 100px - if the text overflows, it must wrap around to next line.
  2. Each column must contain at-most 5 Items.

The number of items are NOT known. If there are less than 5 items in the list they can be kept in the same column. If there are more then they must wrap to next columns. Dynamic FlexBox multi-column

Since I do not know the number of items or their content - I cannot set a height property to the parent list container.

So how can I force the parent container to break after every 5th item into a next column.

.list {
  border: 1px solid black;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}

.item {
  border: 1px solid red;
  width: 100px;
  overflow-wrap: anywhere;
}

.item:nth-child(5n) {
  border: 1px solid blue;
}
<body>
  <div class="list">
    <div class="item">Text 1</div>
    <div class="item">Text 2</div>
    <div class="item">Long Text 3 must wrap to next line</div>
    <div class="item">Text 4</div>
    <div class="item">Text 5</div>
    <div class="item">Text 6</div>
    <div class="item">Text 7 is also long</div>
    <div class="item">Text 8</div>
    <div class="item">Text 9</div>
    <div class="item">Text 10</div>
    <div class="item">Text 11</div>
    <div class="item">Text 12 is last item</div>
  </div>
</body>
Dost Arora
  • 355
  • 3
  • 12
  • The Problem is that Flexbox needs defined breakpoints to wrap. This would be possible if you define a maximum height for the items, but as the content for the items is dynamical that would only work if you for example have a maximum number of words that can be added to an item. – Warden330 Nov 12 '20 at 12:41

2 Answers2

3

Here is an idea using columns. A bit hacky because it requires setting a big height.

.list {
  column-width:100px;
  column-fill:auto;  
  column-gap:0;
  height: 100vh; 
}

.item {
  border: 1px solid red;
}

.item:nth-child(5n) {
  border: 1px solid blue;    
  margin-bottom: 100vh; /* to create the break */
}

body {
  margin:0;
}
<body>
  <div class="list">
    <div class="item">Text 1</div>
    <div class="item">Text 2</div>
    <div class="item">Long Text 3 must wrap to next line</div>
    <div class="item">Text 4</div>
    <div class="item">Text 5</div>
    <div class="item">Text 6</div>
    <div class="item">Text 7 is also long</div>
    <div class="item">Text 8</div>
    <div class="item">Text 9</div>
    <div class="item">Text 10</div>
    <div class="item">Text 11</div>
    <div class="item">Text 12 is last item</div>
  </div>
</body>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
2

Solution using grid.

It was so necessary?

.list {
  border: 1px solid black;
  display: grid;
  grid-template-rows: repeat(5, auto);
  grid-auto-flow: column;
  justify-content: left;

}

.item {
  border: 1px solid red;
  width: 100px;
  overflow-wrap: anywhere;
}

.item:nth-child(5n) {
  border: 1px solid blue;
}
<body>
  <div class="list">
    <div class="item">Text 1</div>
    <div class="item">Text 2</div>
    <div class="item">Long Text 3 must wrap to next line</div>
    <div class="item">Text 4</div>
    <div class="item">Text 5</div>
    <div class="item">Text 6</div>
    <div class="item">Text 7 is also long</div>
    <div class="item">Text 8</div>
    <div class="item">Text 9</div>
    <div class="item">Text 10</div>
    <div class="item">Text 11</div>
    <div class="item">Text 12 is last item</div>
  </div>
</body>
s.kuznetsov
  • 14,870
  • 3
  • 10
  • 25
  • Thanks! This is solution looks good, although it uses gird. One small problem using grid is that it effects other cells also. Like the cell with `Text 8` expands because of the adjoining cell containing `Long Text 3 must wrap to next line`. Is there anyway so that each cell takes up only the required space ? – Dost Arora Nov 12 '20 at 10:13
  • With a grid, this can be done through the template rule, but if the grid is not dynamic. But you can do it with flex, but then .list class should have a fixed height. – s.kuznetsov Nov 12 '20 at 11:31
  • That is the problem - I can't have a fixed height because I do not know the content that i would be placing inside. Each Item must allow the content to wrap - thereby increasing it's height. This [answer](https://stackoverflow.com/a/19576595/8655856) seems to solve it using a `.break` class. But that is done for `row` direction. – Dost Arora Nov 12 '20 at 11:35
  • Yes, with `break` you can do it, but will it be a dynamic transfer?! :) I would not like the solution with `break` class. – s.kuznetsov Nov 12 '20 at 11:43