Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flexbox: Two elements on top of each other in flex-direction: row [duplicate]

Tags:

I am trying to achieve the following:


My first attempt was to use a helper div (green):

JSFiddle

What I could do here, is using JavaScript to move the puple and orange elements out of the helper on mobile screens. But there has to be a plain css way.


My second attempt was to remove the helper and build the Mobile Layout:

JSFiddle


Is there a way to place two elements on top of each other in flex-direction: row? (second attempt)

like image 430
Marc Avatar asked Aug 02 '16 19:08

Marc


People also ask

How do you put flex items on top of each other?

To display the items vertically, use flex-direction: column and the items will stack on top of one another in a column instead of side-by-side in a row. "and positions it relative to it's closest positioned parent" - this would be true if parent's position was anything but default(static).

How do I make items stack on top of each other in CSS?

Using CSS position property: The position: absolute; property is used to position any element at the absolute position and this property can be used to stack elements on top of each other. Using this, any element can be positioned anywhere regardless of the position of other elements.

How do you align two flex items side-by-side?

Just use flex-direction: row with flex-wrap: wrap . Then make each element long enough to occupy a full row. Reduce the flex-basis on the elements that are to share a row. With flex-grow: 1 defined in the flex shorthand, there's no need to use calc() .

Does flexbox work with position relative?

Relative positioning keeps elements in the normal flow. That means that after you position them, their original location is still occupying space. Absolute positioning removes elements from the normal flow. These elements do not take up space, so they can be aligned without disturbing the surrounding layout.


2 Answers

You could do this with Flexbox but you need to use fixed height on flex container. Here is Fiddle

Basically you use flex-wrap: wrap with flex-direction: column and make first item take 100% height and set width in %. Then you change order with media queries and height.

* {
  box-sizing: border-box;
}
main,
div {
  display: flex;
  padding: 1rem;
}
.desktop {
  flex-direction: column;
  flex-wrap: wrap;
  height: 400px;
  width: 100%;
}
div {
  flex: 1;
  width: 30%;
}
[orange] {
  background-color: #FFAD77;
  flex: 0 0 70%;
}
[yellow] {
  background-color: #FFE377;
  flex: 0 0 100%;
  width: 70%;
}
[purple] {
  background-color: #FF77C8;
}
@media(max-width: 480px) {
  .desktop div {
    flex: 1;
    width: 100%;
  }
  div[orange] {
    order: -1;
    flex: 2;
  }
  div[yellow] {
    flex: 5;
  }
  div[purple] {
    flex: 1;
  }
}
<div class="desktop">
  <div yellow>lorem</div>
  <div orange>lorem</div>
  <div purple>lorem</div>
</div>
like image 197
Nenad Vracar Avatar answered Feb 19 '23 09:02

Nenad Vracar


No, but the alternative isn't deadly. If you use absolute positioning, you will have much more control over the layout at different screen sizes.

function toggleLayout() {
  document.querySelector('main').classList.toggle('mobile');
}
main {
  position: relative;
  width: 600px;
  height: 400px;
}

main div {
  position: absolute;
  top: 0; bottom: 0;
  left: 0; right: 0;
}

main.mobile div {
  position: static;
  width: 100%;
  height: 33.3%;
}

[orange] {
  background-color: #FFAD77;
  bottom: 40%;
  left: 66.6%;
}

[yellow] {
  background-color: #FFE377;
  right: 33.3%;
}

[purple] {
  background-color: #FF77C8;
  top: 60%;
  left: 66.6%;
}
<main>
  <div orange></div>
  <div yellow></div>
  <div purple></div>
</main>
<button onclick="toggleLayout()">toggleLayout</button>
like image 32
4castle Avatar answered Feb 19 '23 10:02

4castle