htmljquerycssflexboxcss-grid

How to change Flex Order on mobile compared to desktop?


So I am having issues trying to swap divs 1 and 2 around on mobile.

Mobile the order should be divs 1, 2 and 3 stacked in that order.

Then above 768px, the order needs to be div 2 on the left set at 30% width. Then on the right divs 1 and 3 need to be stacked taking up the remainder on the right.

Not sure how I can do this. I did try it without the wrapper but I couldn't get it to work, this is the closest I have got.

Can anyone help me please?

.container {
  display: flex;
  flex-direction: column; 
  gap: 10px;
}


@media (min-width: 768px) {
  .container {
    flex-direction: row; 
  }

  .specs {
    flex: 0 0 30%; 
    order: 1; 
  }

  .content-buttons {
    flex: 0 0 70%; 
    display: flex;
    flex-direction: column; 
    gap: 10px;
    order: 2; 
  }

  .content {
    flex: 1; 
    order: 1;
  }

  .buttons {
    flex: 1; 
    order: 2;
  }
}

/* Borders for visualization */
.content {border: 1px solid red;}
.specs {border: 1px solid green;}
.buttons {border: 1px solid blue;}
<div class="container">
  <div class="specs">2</div>
  <div class="content-buttons">
    <div class="content">1</div>
    <div class="buttons">3</div>
  </div>
</div>


Solution

  • Desktop-View-Screenshot

    Mobile-View-Screenshot

    Live-Demo-Js-Fiddle

    Note: The issue with your code is, if we group the 1 & 3 in a separate div, with css we can't insert 2 in between 1 & 3 div, we might the help of javascript to do DOM manipulation and then append 2 in between 1 & 3.

    Using Grid-layout system this problem can be fixed by ordering spec, content, button divs in html itself. I have removed the div content-buttons and kept the html very simple like below.

    <div class="container">
      <div class="specs">2</div>
      <div class="content">1</div>
      <div class="buttons">3</div>
    </div>
    

    Solution Desktop view: Keep the order of divs like - 2, 1, 3 by specifying the layout using grid-template-columns: repeat(2, 1fr); which will take only 2 columns in a row, then by giving grid-row: 1/-1; makes the 2 div take enough space vertical and moves the 3rd div below 1st div. Refer the desktop view screenshot for this.

    Take enough vertical space in a single row for the 2nd div.

    .specs {
      grid-row: 1/-1;
    }
    

    Solution for mobile view: using grid-template-columns: 1fr will make the divs order as - 1,2,3 one below the other. Now the can keep the order of the specs class in second by using grid-row: 2; and for the content class grid-row: 1 make the content div to stay in the order 1.

    @media only screen and (max-width: 768px) {
    .container {
        grid-template-columns: 1fr;
    }    
    
    .content {
        grid-row: 1;
    }
    .specs {
        grid-row: 2;
    }
    }
    

    Overall Solution using Grid below. Please make sure to the the demo in js-fiddle. Running the snippet here can sometimes don't show the layout, please do view it in a full page.

    .container {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      grid-template-rows: repeat(3, 100px);
      grid-gap: 10px;
    }
    
    .specs {
      grid-row: 1/-1;
    }
    
    @media only screen and (max-width: 768px) {
      .container {
        grid-template-columns: 1fr;
      }
    
      .content {
        grid-row: 1;
      }
    
      .specs {
        grid-row: 2;
      }
    }
    
    /* Borders for visualization */
    .content {
      border: 1px solid red;
    }
    
    .specs {
      border: 1px solid green;
    }
    
    .buttons {
      border: 1px solid blue;
    }
    <html>
    
    <head>
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <div class="container">
      <div class="specs">2</div>
      <div class="content">1</div>
      <div class="buttons">3</div>
    </div>
    
    </html>