Search code examples
csslayoutflexbox

Three div / two column layout - possible with Flexbox?


I've been trying to achieve the layout below using flexbox. I originally had a left hand sidebar containing the image & navigation, and a main content area. On mobile, the sidebar used to wrap under the main content.

The problem with that is that I need the image to remain at the top on mobile, so I've been trying with three sibling divs in one wrapper div.

Is this even possible with flexbox or will I need to use css grid?

enter image description here


Solution

  • Although CSS Grid would be the best approach to achieve the lay-out you want, it is possible using CSS Flexbox.

    You just have to create a wrapper div with three divs inside (when doing a mobile first approach) and with .content set to flex: 1 to stretch out the height of your viewport.

    Then for desktop (in this case @media screen and (min-width: 1000px)), change the order (MDN reference of order) of .navigation and .content and give all three divs appropriate widths according to their needs. The only change to div.wrapper is that it needs flex-flow: column wrap to wrap correctly.

    Screen resize of desktop to mobile

    .wrapper {
      display: flex;
      flex-direction: column;
      height: 100%;
      min-height: 100%;
    }
    
    .box {
      display: flex;
    }
    
    .content {
      flex: 1;
    }
    
    @media screen and (min-width: 1000px) {
      .wrapper {
        flex-flow: column wrap;
      }
      
      .navigation {
        order: 2;
      }
      
      .content {
        order: 3;
      }
      
      .image,
      .navigation {
        width: 200px;
        flex: 50%;
      }
      
      .content {
        width: calc(100% - 200px);
        flex: 0 0 100%;
      }
    }
    
    
    /* Generic styling */
    
    html,
    body {
      height: 100%;
    }
    
    body {
      margin: 0;
      padding: 0;
    }
    
    .image {
      background: orange;
      height: 60px;
    }
    
    .content {
      background: lightblue;
    }
    
    .navigation {
      background: lightgreen;
      height: 60px;
    }
    <div class="wrapper">
      <div class="box image">Image</div>
      <div class="box content">Content</div>
      <div class="box navigation">Navigation</div>
    </div>