Search code examples
htmlcssmedia-queriesflexbox

Add a row to a nested flex container on media query


I have one primary container that holds all the divs using a flex-direction of row.

A second container that is nested holds two divs that have a flex-direction of column, to stack up two divs in one row in the outer container.

Using flex-box and media query, I was attempting to change the existing two row column div 'smaller-container' into a three row column div once the browser width is less than 1000px.

I tried doing this by creating a third empty div within smaller-container and swapping its order with a div outside the smaller-container once the browser width is less than 1000px.

It didn't work. I think this is because the two divs in question (the empty div and the outer div) are at a different nesting level.

It would be great if someone can find a solution to turn the two row in one column to three row in one column.

Even better if that solution has no need of a nested container. Javascript solution is also welcome if it doesn't require a plugin.

Image of how it should look:

enter image description here

/*Basic Reset*/

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
html,
body {
  height: 100%;
}
body {
  max-width: 1366px;
  margin: auto;
  width: 100%;
}
.container {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
}
.box-1 {
  order: 1;
  background-color: red;
  height: 150px;
  width: 50%;
}
.smaller-container {
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  width: 50%;
  order: 2;
}
.box-2 {
  order: 3;
  background-color: blue;
  height: 75px;
  width: 100%;
}
.box-3 {
  order: 4;
  background-color: green;
  height: 75px;
  width: 100%;
}
.box-4 {
  order: 5;
  width: 100%;
}
.box-5 {
  order: 6;
  background-color: orange;
  height: 150px;
  width: 100%;
}
@media screen and (max-width: 1000px) {
  .box-2 {
    height: 50px;
  }
  .box-3 {
    height: 50px;
  }
  /******* Here we swap the empty div that hasbeen existing in the smaller container
        with an outer div ********/
  .box-5 {
    order: 5;
    height: 50px;
  }
  .box-4 {
    order: 6;
    background-color: purple;
    height: 150px;
  }
}
[image of desired solution][1] [1]:https://i.sstatic.net/vlvlx.png
<div class="container">
  <div class="box-1"></div>
  <div class="smaller-container">
    <div class="box-2"></div>
    <div class="box-3"></div>
    <div class="box-4"></div>
  </div>
  <div class="box-5"></div>
</div>

https://jsfiddle.net/lukindo/nuv603h9/1/


Solution

  • Well, you're right that the order property doesn't work at different nesting levels. It only works among siblings.

    Scripting is one option you can pursue. Another, a bit hackish, is to duplicate an HTML element. Specifically, place the orange box element (.box-5) in both the primary and nested container.

    Then use display: none on both orange and purple boxes per your media query.

    Here's an example:

    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    html,
    body {
      height: 100%;
    }
    body {
      max-width: 1366px;
      margin: auto;
      width: 100%;
    }
    .container {
      display: flex;
      flex-wrap: wrap;
      flex-direction: row;
    }
    .box-1 {
      order: 1;
      background-color: red;
      height: 150px;
      width: 50%;
    }
    .smaller-container {
      display: flex;
      flex-wrap: wrap;
      flex-direction: row;
      width: 50%;
      order: 2;
    }
    .box-2 {
      order: 3;
      background-color: blue;
      height: 75px;
      width: 100%;
    }
    .box-3 {
      order: 4;
      background-color: green;
      height: 75px;
      width: 100%;
    }
    .smaller-container > .box5 {
      display: none;
    }
    .container > .box-5 {
      order: 6;
      background-color: orange;
      height: 150px;
      width: 100%;
    }
    @media screen and (max-width: 1000px) {
      .box-2 {
        height: 50px;
      }
      .box-3 {
        height: 50px;
      }
      .container > .box-4 {
        order: 6;
        background-color: purple;
        height: 150px;
        width: 100%;
      }
      .smaller-container > .box-5 {
        display: block;
        height: 50px;
        background-color: orange;
        width: 100%;
        order: 6;
      }
      .container > .box-5 {
        display: none;
      }
    }
    <div class="container">
      <div class="box-1"></div>
      <div class="smaller-container">
        <div class="box-2"></div>
        <div class="box-3"></div>
        <div class="box-5"></div>
      </div>
      <div class="box-4"></div>
      <div class="box-5"></div>
    </div>

    Revised Fiddle