Jeremy H. Brown
Jeremy H. Brown

Reputation: 63

Column flexbox: wrap to width limit, then grow height?

I'd like to make a flexbox where:

  1. Items are arranged in columns
  2. As long as all items will fit within a fixed width, wrapping creates more columns.
  3. If the items need more space, the flexbox grows vertically after that, with a vertical scrollbar rather than a horizontal one.

Is there any way to achieve this without Javascript?

The following does the right thing until there are too many items, but then it overflows horizontally rather than vertically.

<div style="height: 100%; width: 100%; overflow-y: auto;">
  <div style="display: flex; flex-direction: column; flex-wrap: wrap; width: 100%; height: 100%; overflow-y: auto">
    <div style="width: 15em;"> a </div>
    <div style="width: 15em;"> b </div>
    <div style="width: 15em;"> c </div>
    <div style="width: 15em;"> d </div>
    <div style="width: 15em;"> e </div>
    <div style="width: 15em;"> f </div>
    <div style="width: 15em;"> g </div>
    <div style="width: 15em;"> h </div>
    <div style="width: 15em;"> i </div>
    <div style="width: 15em;"> j </div>
    <div style="width: 15em;"> k </div>
    <div style="width: 15em;"> l </div>
    <div style="width: 15em;"> m </div>
    <div style="width: 15em;"> n </div>
    <div style="width: 15em;"> o </div>
    <div style="width: 15em;"> p </div>
    <div style="width: 15em;"> q </div>
    <div style="width: 15em;"> r </div>
    <div style="width: 15em;"> s </div>
    <div style="width: 15em;"> t </div>
    <div style="width: 15em;"> u </div>
  </div>
</div>

Upvotes: 6

Views: 4465

Answers (1)

tao
tao

Reputation: 90277

Is this what you are trying to achieve?

.grandParent {
  height: 100%;
  width: 100%;
}
.parent {
  display: flex; 
  flex-direction: row; 
  flex-wrap: wrap; 
  width: 100%; 
  height: 100%; 
}
.parent > div {
  min-height: 3em;
  flex-basis: 15em;
  background-color: #f5f5f5;
  padding: 20px;
  box-sizing: border-box;
  margin: 3px;
  border: 1px solid #eee;
  text-align: center;
}
<div class="grandParent">
      <div class="parent">
        <div> item 1</div>
        <div> item 2</div>
        <div> item 3</div>
        <div> item 4</div>
        <div> item 5</div>
        <div> item 6</div>
        <div> item 7</div>
        <div> item 8</div>
        <div> item 9</div>
        <div> item 10</div>
        <div> item 11</div>
        <div> item 12</div>
        <div> item 13</div>
        <div> item 14</div>
        <div> item 15</div>
        <div> item 16</div>
        <div> item 17</div>
        <div> item 18</div>
        <div> item 19</div>
        <div> item 20</div>
        <div> item 21</div>
        <div> item 22</div>
        <div> item 23</div>
        <div> item 24</div>
        <div> item 25</div>
        <div> item 26</div>
        <div> item 27</div>
        <div> item 28</div>
        <div> item 29</div>
        <div> item 30</div>
      </div>
    </div>

Or this?

.grandParent {
  height: 100%;
  width: 100%;
}
.parent {
  -webkit-column-width: 15em;
  -moz-column-width: 15em;
  column-width: 15em;
}
.parent > div {
  min-height: 3em;
  background-color: #eee;
  box-sizing: border-box;
  margin-bottom: 10px;
  border: 1px solid #eee;
  text-align: center;
  break-inside: avoid-column;
  -webkit-column-break-inside: avoid;
}
h2 {
    -webkit-column-span: all;
    column-span: all;
}
<div class="grandParent">
  <div class="parent">
    <div>item 1</div>
    <div>item 2</div>
    <div>item 3</div>
    <div>item 4</div>
    <div>item 5</div>
    <div>item 6</div>
    <div>item 7</div>
    <div>item 8</div>
    <div>item 9</div>
    <div>item 10</div>
    <div>item 11</div>
    <div>item 12</div>
    <h2>Some cool title</h2>
    <div>item 13</div>
    <div>item 14</div>
    <div>item 15</div>
    <div>item 16</div>
    <div>item 17</div>
    <div>item 18</div>
    <div>item 19</div>
    <div>item 20</div>
    <div>item 21</div>
    <div>item 22</div>
    <div>item 23</div>
    <div>item 24</div>
    <div>item 25</div>
    <div>item 26</div>
    <div>item 27</div>
    <div>item 28</div>
    <div>item 29</div>
    <div>item 30</div>
  </div>
</div>

Upvotes: 5

Related Questions