1

So imagine we have four divs. On a small screen, I want them to look like the following picture. 4 boxes stacked one on top of the other and centered nicely. Easy enough. 4 boxes stacked one on top of the other

Once the screen is big enough, I'd like for the 3rd div in the row to pop over to the right side, while still keeping the other 3 stacked and on the left side. How would I do this with flexbox or some other css technique?

Thanks very much. I'm sure this is a duplicate somehow but I wasn't able to find my exact scenario. four boxes with the 3rd one to the right of the others

tnrich
  • 8,006
  • 8
  • 38
  • 59

2 Answers2

1

If you use a @media query for the breakpoint, you could reorder the the flex children and force linebreaks by using flex-wrap: wrap, percentage widths and margin-right for child2 and child4 to have them in the same width as child1

body {
  background: lightblue;
}

.flex {
  display: flex;
  flex-direction: column;
  padding: 1em;
  border:1px solid #000;
}

.flex .child {
  font-size: 3em;
  padding: 0.1em;
  border: 1px solid #000;
  margin-bottom: .5em;
  box-sizing: border-box;
}

@media (min-width: 600px) {
  .flex {
    flex-direction: row;
    flex-wrap: wrap;
  }
  .flex .child {
    order: 3;
    width: 33.33%;
  }
  .flex .child:nth-of-type(1) {
    order: 1;
    width: 33.33%;
  }
  .flex .child:nth-of-type(3) {
    order: 2;
    width: 66.66%;
  }
  .flex .child:nth-of-type(2), .flex .child:nth-of-type(4) {
    margin-right: 66.66%;
  } 
}
<div class="flex">
  <div class="child">1</div>
  <div class="child">2</div>
  <div class="child">3</div>
  <div class="child">4</div>
</div>

jsFiddle: https://jsfiddle.net/azizn/3snvjyp5/


Edit: dynamic heights / faux-masonry layout

If you want child3 to have a tall height without creating whitespace, you could apply position: absolute so that it doesn't affect the flow while all other children are under each other with margin-right equal to child3's width:

body {
  background: lightblue;
}

.flex {
  display: flex;
  flex-direction: column;
  padding: 1em;
  border:1px solid #000;
  position: relative;
}

.flex .child {
  font-size: 3em;
  padding: 0.1em;
  border: 1px solid #000;
  margin-bottom: .5em;
  box-sizing: border-box;
}

@media (min-width: 600px) {
  .flex {
    flex-direction: row;
    flex-wrap: wrap;
  }
  .flex .child {
    width: 33.33%;
    margin-right: 66.66%;
  }
  .flex .child:nth-of-type(3) {
    width: 62.66%;
    position: absolute;
    top: 2%; right: 2%;
    margin-right: 0;
  }
}
<div class="flex">
  <div class="child" style="height: 100px;">1</div>
  <div class="child" style="height: 200px;">2</div>
  <div class="child" style="height: 600px;">3</div>
  <div class="child" style="height: 400px;">4</div>
</div>

This code is more simplified since we do not need to reorder the children.

jsFiddle: https://jsfiddle.net/azizn/d0pk8p89/

Aziz
  • 7,685
  • 3
  • 31
  • 54
  • Does this rely on the divs having the same heights? I added heights to your fiddle: https://jsfiddle.net/3snvjyp5/5/ I'd like for div 2 and 4 to slide up and fill the space left by div3 if possible. – tnrich May 02 '16 at 07:23
  • Yes and no. If `child3` is taller than `child1` it will create whitespace between `child1` and `child2`.. the others can have different heights (2 and 4) - see example: https://jsfiddle.net/azizn/ema05hbg/ - did you want this to behave differently? – Aziz May 02 '16 at 07:26
  • Yes. I should have made it clearer when asking the question initially. Divs 2 and 4 need to slide up next to div 1 even if child3's height > child1's height – tnrich May 02 '16 at 07:28
0

if you want to do it in a serial order than you can use flexbox and just assign a min-width to all your components and they flex:1; so they will try to fit in till they have room and stack only if need be..

If you want the screen to be occupied if if div 3 can fit and div 2 cannot then you might want to look at Jquery masonry..it will help you fill the space with whichever content can fit in..

Dhaval Chheda
  • 4,637
  • 5
  • 24
  • 44
  • I'm using React with this project currently so would rather not have to mess with jquery masonry if at all possible, but maybe it is the most viable solution. – tnrich May 02 '16 at 07:31
  • if you don't want to reinvent the wheel then it has pretty much everything there – Dhaval Chheda May 02 '16 at 07:33