Control item count in a row with flexbox

后端 未结 2 1938
长发绾君心
长发绾君心 2021-01-14 06:00

I want to show 4 items in 1st row as it is, but only 3 in second line, and then 4 in 3rd line and 3 in 4th line and so on...

I have achieved this by nth-child<

相关标签:
2条回答
  • 2021-01-14 06:24

    You only need to consider one rule like below:

     /*7 = 4 (1st row) + 3 (2nd row) and 5 = 1st element in 2nd row (4 + 1)*/
    .grid-wrapper .grid-item:nth-child(7n + 5) {
      width: calc(100%/3);
      flex-grow:0;
    }
    

    The trick is to make one element bigger to trigger the wrap then rely on flex-grow to fill the space.

    Full code

    * {
      box-sizing: border-box;
    }
    
    .grid-wrapper {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
    }
    
    .grid-wrapper .grid-item {
      width: 25%;
      text-align: center;
      padding: 5px;
      flex-grow: 1;
    }
    
    .grid-wrapper .grid-item:nth-child(7n + 5) {
      width: calc(100%/3);
      flex-grow:0;
    }
    
    p {
      background: #ffffd;
      padding: 15px;
    }
    <div class="grid-wrapper">
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div><div class="grid-item">
        <p>Grid Item</p>
      </div>
    </div>

    0 讨论(0)
  • 2021-01-14 06:30

    Is it possible by flex? or grid?

    Here is a solution using grid which is easier to construct:

    • consider a 12-column grid layout using grid-template-columns: repeat(12, 1fr),

    • place each grid-item into 4 columns by using grid-column: span 3,

    • 7 grid-items are repeating in a pattern; which means every even row has 3 items with nth-child indices 7n, 7n - 1 and 7n - 2.

    See demo below:

    * {
      box-sizing: border-box;
    }
    
    .grid-wrapper {
      display: grid; /* grid container */
      grid-template-columns: repeat(12, 1fr); /* 12-column layout */
    }
    
    .grid-wrapper .grid-item {
      text-align: center;
      padding: 5px;
      grid-column: span 3; /* 4 items in a row */
    }
    
    .grid-wrapper .grid-item:nth-child(7n - 2),
    .grid-wrapper .grid-item:nth-child(7n - 1),
    .grid-wrapper .grid-item:nth-child(7n) { /* even row */
      grid-column: span 4; /* 3 items in the even row */
    }
    
    p {
      background: #ffffd;
      padding: 15px;
    }
    <div class="grid-wrapper">
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
    
    
    </div>


    Flexbox solution

    And I'd use just about the same nth-child logic in the case of a flexbox and the only change in your code would be the below:

    .grid-wrapper .grid-item:nth-child(7n - 2),
    .grid-wrapper .grid-item:nth-child(7n - 1),
    .grid-wrapper .grid-item:nth-child(7n) { /* even row */
      width: 33.33%;
    }
    

    See demo below:

    * {
      box-sizing: border-box;
    }
    
    .grid-wrapper {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
    }
    
    .grid-wrapper .grid-item {
      width: 25%;
      text-align: center;
      padding: 5px;
    }
    
    p {
      background: #ffffd;
      padding: 15px;
    }
    
    /* ADDED THESE */
    .grid-wrapper .grid-item:nth-child(7n - 2),
    .grid-wrapper .grid-item:nth-child(7n - 1),
    .grid-wrapper .grid-item:nth-child(7n) { /* even row */
      width: 33.33%;
    }
    <div class="grid-wrapper">
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
      <div class="grid-item">
        <p>Grid Item</p>
      </div>
    
    
    </div>


    On a separate note, if you interested in having n items in a row with flexboxes, the below answers may give you more information:

    • 5 items per row, auto-resize items in flexbox
    • How to start a new line with a particular item with Flexbox?
    0 讨论(0)
提交回复
热议问题