Search code examples
cssflexbox

How to get 33.33% width flex divs in multiple rows?


I am trying to get flex divs stacked in rows of 3. Sometimes I will have 3 divs, sometimes 6 or 21, etc. I got the widths and paddings figured out, but I can't figure out how to get them to start a new row after each set of 3.

How can I achieve that? Right now it's putting them all in 1 line.

The HTML code is like this:

<div id="container">

  <div class="sections__container">

        <div class="sections__container__a">A-1</div>
        <div class="sections__container__b">A-2</div>
        <div class="sections__container__c">A-3</div>

        <div class="sections__container__a">B-1</div>
        <div class="sections__container__b">B-2</div>
        <div class="sections__container__c">B-3</div>

  </div> 

</div>

Each flex div is using CSS like:

width: 33.33%;
height: 100%;
float: left;
flex-grow: 1;

And here's a jsFiddle to make things easier: https://jsfiddle.net/xr746syj/

Thank you so much for any advice :)


Solution

  • First, you need to use flex-wrap: wrap so that your rows break at the proper point.

    Second, you're using margins and need to account for them in your width calculations.

    So, if you're saying a block is 33.33% but has margin-left: 5px, you need to use width: calc(33.33% - 5px).

    Last, I removed the floats from your code, since they are useless properties when applied to flex children. Your code could be massively simplified by creating a common class that contained all the shared values between each section.

    Here's the full, working code:

    * {
      box-sizing: border-box;
    }
    
    #container {
      width: 600px;
      margin: 0 auto;
      background-color: #ececec;
      padding: 10px;
      margin-bottom: 30px;
    }
    
    .sections__container {
      margin: 0 auto;
      max-width: 600px;
      display: flex;
      flex-wrap: wrap;
    }
    
    .sections__container__a {
      margin-right: 5px;
      width: calc(33.33% - 5px);
      height: 100%;
      border-radius: 4px;
      flex-grow: 1;
      background-color: #FFFFFF;
      font-size: 0.80rem;
      padding: 15px 0px 10px 0px;
      font-weight: 600;
      margin-bottom: 10px;
      text-align: center;
    }
    
    .sections__container__b {
      margin: 0 5px;
      width: calc(33.33% - 10px);
      height: 100%;
      border-radius: 4px;
      flex-grow: 1;
      background-color: #FFFFFF;
      font-size: 0.80rem;
      padding: 15px 0px 10px 0px;
      font-weight: 600;
      margin-bottom: 10px;
      text-align: center;
    }
    
    .sections__container__c {
      margin-left: 5px;
      width: calc(33.33% - 5px);
      height: 100%;
      border-radius: 4px;
      flex-grow: 1;
      background-color: #FFFFFF;
      font-size: 0.80rem;
      padding: 15px 0px 10px 0px;
      font-weight: 600;
      margin-bottom: 10px;
      text-align: center;
    }
    <div id="container">
      <div class="sections__container">
        <div class="sections__container__a">A-1</div>
        <div class="sections__container__b">A-2</div>
        <div class="sections__container__c">A-3</div>
    
        <div class="sections__container__a">B-1</div>
        <div class="sections__container__b">B-2</div>
        <div class="sections__container__c">B-3</div>
      </div>
    </div>

    jsFiddle