Responsive CSS: shift middle div rows to a separate column after reaching media query break point

Viewed 305

I am using CSS media queries to create a responsive layout.

In my current HTML layout I use flexbox to align rows of divs:

<div id="page">
  <div id="div-1">DIV 1</div>
  <div id="div-2">DIV 2</div>
  <div id="div-3">DIV 3</div>
  <div id="div-4">DIV 4</div>
</div>

and CSS:

#page {
  display: flex;
  flex-direction: column;
  align-items: center;
}

[id^="div-"] {
  border: 1px solid #ccc;
  margin-bottom: 10px;
  width: 50vw;
}

#div-1 {
  height: 50px;
}

#div-2 {
  height: 70px;
}

#div-3 {
  height: 150px;
}

#div-4 {
  height: 100px;
}

Here is Jsfiddle for you to tinker with.

It is what I am after for a smaller viewports, but would like to switch things around on the next media query break point to have 2 middle divs to shift to a separate column on the right like this:

enter image description here

How do I achieve that? It is pretty obvious for me how to shift last few div rows to another column, but not sure how to tackle the middle rows...

Is there a way to do it by using flexbox or grid?

1 Answers

Another possible solution is to use the order-property in combination with Flexbox (drawback: you'll need a tiny bit of extra html and set the height of the #page container; advantages: flexible div heights and gap sizes):

#page {
  display: flex;
  flex-direction: column;
  align-items: center;
}

[id^="div-"] {
  border: 1px solid #ccc;
  margin-bottom: 10px;
  width: 50vw;
}

#div-1 {
  height: 50px;
  background: lightgreen;
}

#div-2 {
  height: 70px;
  background: lightyellow;
}

#div-3 {
  height: 150px;
  background: lightcoral;
}

#div-4 {
  height: 100px;
  background: lightblue;
}

@media (max-width: 1000px) {
  #page {
    flex-wrap: wrap;
    height: 300px;
  }
  #small-screen-spacer {
    order: 3;
    align-self: stretch;
    flex: 1 0 100%;
    margin-right: 10px;
  }
  #div-1 {
    order: 1;
  }
  #div-2 {
    order: 4;
  }
  #div-3 {
    order: 5;
  }
  #div-4 {
    order: 2;
  }
}
<div id="page">
  <div id="div-1">DIV 1</div>
  <div id="div-2">DIV 2</div>
  <div id="div-3">DIV 3</div>
  <div id="div-4">DIV 4</div>
  <div id="small-screen-spacer"> </div>
</div>

The #small-screen-spacer will fill the entire available vertical space, so that all elements that come after the spacer (defined by the order property) are moved to the second column. Additionally you can set the desired gap between the two columns by setting margin-right on the spacer to your desired value.

Fiddle

Related