Skip to content Skip to sidebar Skip to footer

Desktop And Mobile Flexbox Layouts Without Nested Containers

I have 3 divs that must be in a certain order for the mobile layout, but I have to break out the 2nd div as a sidebar for the desktop layout. So for mobile: ===== | div1 | ===== |

Solution 1:

Based on how you want nr2 to look like when in desktop layout, here is another option, using a pseudo element to create the illusion of them all fill their parent.

The great doing like this is no fixed height is needed and both columns will fill its parent no matter which is bigger

Sample 1

.parent {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.child {
  position: relative;
  padding: 10px;
  border: 2px solid white;
  box-sizing: border-box;
}
.nr1 {
  background-color: lightblue;
  order: -1;
}
.nr2 {
  background-color: lightgreen;
}
.nr3 {
  background-color: lightgray;
}
@media (max-width: 800px) {
  .parent {
    display: block;
  }
  .nr1, .nr3 {
    float:left;
    width: 50.1%;
  }
  .nr2 {
    float:right;
    width: 49.9%;
  }
  .nr3::after,
  .nr2::after {
    content: '';
    position: absolute;
    background-color: inherit;
    left: 0;
    top: 100%;
    width: 100%;
    height: 100vh;
  }
}
<divclass="parent"><divclass="child nr2"> 2 </div><divclass="child nr1"> 1 <br> 1 <br> 1 <br> 1 <br> 1 <br> 1 <br></div><divclass="child nr3"> 3 </div></div>

Sample 2

.parent {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.child {
  position: relative;
  padding: 10px;
  border: 2px solid white;
  box-sizing: border-box;
}
.nr1 {
  background-color: lightblue;
  order: -1;
}
.nr2 {
  background-color: lightgreen;
}
.nr3 {
  background-color: lightgray;
}
@media (max-width: 800px) {
  .parent {
    display: block;
  }
  .nr1, .nr3 {
    float:left;
    width: 50.1%;
  }
  .nr2 {
    float:right;
    width: 49.9%;
  }
  .nr3::after,
  .nr2::after {
    content: '';
    position: absolute;
    background-color: inherit;
    left: 0;
    top: 100%;
    width: 100%;
    height: 100vh;
  }
}
<divclass="parent"><divclass="child nr2"> 2 <br> 2 <br> 2 <br> 2 <br> 2 <br> 2 <br></div><divclass="child nr1"> 1 </div><divclass="child nr3"> 3 </div></div>

Sample 3

.parent {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.child {
  position: relative;
  padding: 10px;
  border: 2px solid white;
  box-sizing: border-box;
}
.nr1 {
  background-color: lightblue;
  order: -1;
}
.nr2 {
  background-color: lightgreen;
}
.nr3 {
  background-color: lightgray;
}
@media (max-width: 800px) {
  .parent {
    display: block;
  }
  .nr1, .nr3 {
    float:left;
    width: 50.1%;
  }
  .nr2 {
    float:right;
    width: 49.9%;
  }
  .nr3::after,
  .nr2::after {
    content: '';
    position: absolute;
    background-color: inherit;
    left: 0;
    top: 100%;
    width: 100%;
    height: 100vh;
  }
}
<divclass="parent"><divclass="child nr2"> 2 </div><divclass="child nr1"> 1 </div><divclass="child nr3"> 3 <br> 3 <br> 3 <br> 3 <br> 3 <br> 3 <br></div></div>

This one uses a pseudo on the parent, to make nr2 look good having a gradient background

.parent {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.child {
  position: relative;
  padding: 10px;
  border: 2px solid white;
  box-sizing: border-box;
}
.nr1 {
  background-color: lightblue;
  order: -1;
}
.nr2 {
  background-color: lightgreen;
}
.nr3 {
  background-color: lightgray;
}
@media (max-width: 800px) {
  .parent {
    display: block;
  }
  .parent::before {
    content: '';
    position: absolute;
    background: linear-gradient(lightgreen, green);
    left: 50.1%;
    top: 2px;
    width: 49.9%;
    height: 100%;
  }
  
  .nr1, .nr3 {
    float:left;
    width: 50.1%;
  }
  .nr2 {
    float:right;
    width: 49.9%;
    border: none;
    background-color: transparent;
  }
  .nr3::after {
    content: '';
    position: absolute;
    background-color: inherit;
    left: 0;
    top: 100%;
    width: 100%;
    height: 100vh;
  }
}
<divclass="parent"><divclass="child nr2"> 2 <br> 2 <br> 2 <br> 2 <br> 2 <br> 2 <br></div><divclass="child nr1"> 1 <br> 1 <br> 1 <br></div><divclass="child nr3"> 3 <br> 3 <br> 3 <br> 3 <br> 3 <br> 3 <br></div></div>

Solution 2:

Here's one way to do it with absolute positioning. Preview this snippet and you'll see your two layouts side by side.

To make it easy to see, I'm just using a .desktop class with the same HTML, but you could easily incorporate a media query instead to switch to that layout on mobile.

.wrapper {
  border: 1px dotted #333;
  position: relative;
  margin: 10px;
  width: 100px;
  float: left;
}

.wrapperdiv {
  height: 100px;
  width: 100px;
}

.div-1 { background: lightblue; }
.div-2 { background: turquoise; }
.div-3 { background: teal; }

/* alternate layout via class, or use media query: */.wrapper.desktop {
  width: 300px;
}

.wrapper.desktop.div-2 {
  position: absolute;
  width: auto;
  height: auto;
  top: 0;
  bottom: 0;
  right: 0;
  left: 100px;
}
<divclass="wrapper"><divclass="div-1">Div 1</div><divclass="div-2">Div 2</div><divclass="div-3">Div 3</div></div><divclass="wrapper desktop"><divclass="div-1">Div 1</div><divclass="div-2">Div 2</div><divclass="div-3">Div 3</div></div>

Solution 3:

I actually thought of a simple solution that does exactly what I want. The tough thing about this is that the page displays a profile for a member of my client. There are almost 500 members and I have no control over the content that they put into their profile. So, no idea of the height of any of the divs and it varies all over the place. The issue with absolute positioning div2 is that if it has longer content than 1 & 3 combined, you lost the bottom of the div under the footer. I can't really use any fixed heights since the amount of content changes from member to member.

My fix was to add a 4th div that did nothing but provide the shaded background for the div2 sidebar. So, in desktop mode, div1 & div2 floated left, with div2 floated right, and div4 (with the shading) set to absolute with top and bottom set to 0 and a lower z-index than div2. In mobile mode, I hide div4 and set the widths of the others to 100% and it all just works.

Post a Comment for "Desktop And Mobile Flexbox Layouts Without Nested Containers"