Search code examples
htmlcssflexboxgrid-layout

Flex container with four divs, need three columns, second column with two rows


For a section on a page, I am trying to display two rectangular divs stacked up between two square divs on either side as big as the height of the two stacked divs, inside these divs are img tags.

I am using this markup because on mobile I want to be able to have them on an un-wrapped flex row with an overflow: hidden parent so I can use a swipe code to translate the X-axis. I am having problems creating this layout for desktop with this markup using the flexbox (No grid, need to support IE11). Has anyone done this layout with this markup? Thanks.

 <div class="flex_container">
   <div class='flex_child square'>
     <img...>
   </div>
   <div class='flex-child rect'>
     <img...>
   </div>
   <div class='flex-child rect'>
     <img...>
   </div>
   <div class='flex-child square'>
     <img...>
   </div>
 </div>

Example by image


Solution

  • Assuming that this will be the main layout of your page you can try to set a fixed height and use column direction with flexbox:

    .flex_container {
      height: 100vh; /*adjust this value like you want*/
      display: flex;
      flex-direction: column;
      flex-wrap:wrap;
    }
    .flex_child {
      background:purple;
      border:2px solid #fff;
      box-sizing:border-box;
      width:calc(100% / 3);
    }
    .square {
      flex:1 1 100%;
    }
    .rect {
      flex:1 1 47%;
    }
    
    body {
      margin: 0;
    }
    <div class="flex_container">
      <div class='flex_child square'></div>
      <div class='flex_child rect  '></div>
      <div class='flex_child rect  '></div>
      <div class='flex_child square'></div>
    </div>

    And in case you want a better browser support you can use float/inline-block by slightly adjust the classes making the 2 squares at the start:

    .flex_container {
      height: 100vh; /*adjust this value like you want*/
    }
    .flex_child {
      background:purple;
      border:2px solid #fff;
      box-sizing:border-box;
      width:calc(100% / 3);
      height:100%;
    }
    .square:nth-child(1) {
      float:left;
    }
    .square:nth-child(2) {
      float:right;
    }
    .rect {
      display:inline-block;
      height:50%;
      vertical-align:top;
    }
    
    body {
      margin: 0;
    }
    <div class="flex_container">
      <div class='flex_child square'></div>
      <div class='flex_child square'></div>
      <div class='flex_child rect  '></div>
      <div class='flex_child rect  '></div>
    </div>

    In case you cannot also change the classes, use some negative margin to rectify the position of the last element:

    .flex_container {
      height: 100vh; /*adjust this value like you want*/
    }
    .flex_child {
      background:purple;
      border:2px solid #fff;
      box-sizing:border-box;
      width:calc(100% / 3);
      height:100%;
    }
    .square:first-child {
      float:left;
    }
    .square:last-child {
      float:right;
      margin-top:-50vh;
    }
    .rect {
      display:inline-block;
      height:50%;
      vertical-align:top;
    }
    
    body {
      margin: 0;
    }
    <div class="flex_container">
      <div class='flex_child square'></div>
      <div class='flex_child rect  '></div>
      <div class='flex_child rect  '></div>
      <div class='flex_child square'></div>
    </div>