skip to Main Content

I have a grid with two columns, and in the columns there are divs with different height and width. It is necessary to know that when we click on a div, its content toggles down (show/hide with jquery), so divs can change their heights also. For showing my contents in importance from screen view top to down, the order is in line (row). My problem is the mobile version because when I resize the page, the order will be by columns, and not as in line.

.grid {position:relative;display:flex;flex-flow:row wrap;justify-content:space-between;width:100%;max-width:1200px;margin:0 auto;padding:20px;background:grey}
.column {position:relative;display:flex;flex-flow:row wrap;align-content:start;width:49.5%;background:white}
.column1 {justify-content:right;}
.column2 {justify-content:left;}
.item {width:97.5%;max-width:720px;max-height:720px;padding:10px;color:#fff;font-size:30px}
.item1 {width:80%;height:100px;background:red}
.item2 {width:50%;height:190px;background:blue}
.item3 {width:40%;height:80px;background:green}
.item4 {width:100%;height:50px;background:yellow}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<main class="grid">
  <div class="column column1">
    <div class="item item1">1</div>
    <div class="item item3">3</div>
  </div>
  <div class="column column2">
    <div class="item item2">2</div>
    <div class="item item4">4</div>
  </div>
</main>

image example what I am looking for

I found a lot of questions/answers about grid and divs order but all of them are in the same columns or rows. I am still looking for a CSS or JS solution.

3

Answers


  1. Chosen as BEST ANSWER

    I accepted Kameron's answer but in the meantime I found a more simple way... First the items of the column 2. must be appended to the column 1., then I put the ex column 2. items between the column 1. items. At the end I do not display the empty column 2.

    if($(window).width() <= 800){
        // 1st step
        $('.item2').appendTo('.column1')
        $('.item4').appendTo('.column1')
        // 2nd step
        $('.item1 + .item3').before($('.item2'));
        $('.item3 + .item5').before($('.item4'));
        // 3rd step
        $('.column2').css('display', 'none');
    }
    

  2. You can use @media only screen to set divs in one column from or to a certain width and use grid but then you will have rows same height and If you don’t want this you can use js to replace childs. like this.

    script.js

    let item1 = document.querySelector(".item1");
    let item2 = document.querySelector(".item2");
    let item3 = document.querySelector(".item3");
    let item4 = document.querySelector(".item4");
    
    let doneOnce = false;
    let prevWidth = false;
    let widthChanged = false;
    
    document.addEventListener("DOMContentLoaded", function () {
        width = document.body.clientWidth;
        if (width <= 600) {
            item3.replaceWith(item2);
            item4.parentElement.insertBefore(item3, item4);
        }
    });
    
    window.addEventListener("resize", () => {
        width = document.body.clientWidth;
        height = document.body.clientHeight;
        if (
            (width <= 600 && prevWidth > 600 && prevWidth) ||
            (width > 600 && prevWidth <= 600 && prevWidth)
        ) {
            doneOnce = false;
            widthChanged = true;
        }
       
        if (width <= 600 && !doneOnce && widthChanged) {
            item3.replaceWith(item2);
            item4.parentElement.insertBefore(item3, item4);
            doneOnce = true;
        } else if (width > 600 && !doneOnce && widthChanged) {
            item2.replaceWith(item3);
            item4.parentElement.insertBefore(item2, item4);
            doneOnce = true;
        }
        prevWidth = width;
    });
    

    style.css

    body {
        margin: 0;
    }
    * {
        box-sizing: border-box;
    }
    .grid {
        position: relative;
        display: flex;
        flex-flow: row wrap;
        justify-content: space-between;
        width: 100%;
        max-width: 1200px;
        margin: 0 auto;
        padding: 20px;
        background: grey;
    }
    .column {
        position: relative;
        display: flex;
        flex-flow: row wrap;
        align-content: start;
        width: 49.5%;
        background: white;
    }
    .column1 {
        justify-content: right;
    }
    .column2 {
        justify-content: left;
    }
    .item {
        width: 97.5%;
        max-width: 720px;
        max-height: 720px;
        padding: 10px;
        color: #fff;
        font-size: 30px;
    }
    .item1 {
        width: 80%;
        height: 100px;
        background: red;
    }
    .item2 {
        width: 50%;
        height: 190px;
        background: blue;
    }
    .item3 {
        width: 40%;
        height: 80px;
        background: green;
    }
    .item4 {
        width: 100%;
        height: 50px;
        background: yellow;
    }
    
    @media only screen and (max-width: 600px) {
        .grid {
            flex-direction: column;
            align-items: center;
        }
        .grid > div {
            justify-content: center;
        }
    }
    

    index.html

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
     <main class="grid">
            <div class="column column1">
                <div class="item item1">1</div>
                <div class="item item3">3</div>
            </div>
            <div class="column column2">
                <div class="item item2">2</div>
                <div class="item item4">4</div>
            </div>
        </main>
    
    Login or Signup to reply.
  3. This is a bit of an odd request that cannot be handled with modern CSS.

    I created a function that swaps the elements by inserting a marker at the desired location of object 1. There are more details on this function located in the comments of the JS.

    I then created a MediaQueryList by calling the matchMedia method on the window object.

    A MediaQueryList object stores information on a media query applied to a document, with support for both immediate and event-driven matching against the state of the document. – MDN

    So with this said, I used an event-driven listener that is invoked by a conditional statement whenever the screen is below or equal to 1000px.

    function swapElements(obj1, obj2) {
      // create marker element and insert it where object 1 is
      var mkr = document.createElement("div");
      obj1.parentNode.insertBefore(mkr, obj1);
    
      // move object 1 to right before object 2
      obj2.parentNode.insertBefore(obj1, obj2);
    
      // move object 2 to right before where object 1 used to be
      mkr.parentNode.insertBefore(obj2, mkr);
    
      // remove temporary marker node
      mkr.parentNode.removeChild(mkr);
    }
    
    // create function with if - else statement
    function setMediaQuery(x) {
      if (x.matches) {
        swapElements(document.querySelector(".item3"), document.querySelector(".item2"));
      }
    }
    
    // create a MediaQueryListObject
    const mediaQueryMax = window.matchMedia("(max-width: 1000px)");
    const mediaQueryMin = window.matchMedia("(min-width: 1000px)");
    
    // call the match function at run time
    setMediaQuery(mediaQueryMax);
    
    // add the match function as a listener for state changes
    mediaQueryMax.addListener(setMediaQuery)
    mediaQueryMin.addListener(setMediaQuery)
    .grid {
      position: relative;
      display: flex;
      flex-flow: row wrap;
      justify-content: space-between;
      max-width: 1200px;
      margin: 0 auto;
      padding: 20px;
      background: grey
    }
    
    .column {
      position: relative;
      display: flex;
      flex-flow: row wrap;
      align-content: start;
      width: 49.5%;
      background: white
    }
    
    .column1 {
      justify-content: right;
    }
    
    .column2 {
      justify-content: left;
    }
    
    .item {
      width: 97.5%;
      max-width: 720px;
      max-height: 720px;
      padding: 10px;
      color: #fff;
      font-size: 30px
    }
    
    .item1 {
      width: 80%;
      height: 100px;
      background: red
    }
    
    .item2 {
      width: 50%;
      height: 190px;
      background: blue
    }
    
    .item3 {
      width: 40%;
      height: 80px;
      background: green
    }
    
    .item4 {
      width: 100%;
      height: 50px;
      background: yellow
    }
    
    @media only screen and (max-width: 1000px) {
      .column {
        width: 100%;
      }
      .column1,
      .column2 {
        justify-content: center;
      }
      .grid,
      .column {
        row-gap: 1em;
      }
      .grid {
        background: transparent;
        border: solid 18px grey;
      }
    }
    <main class="grid">
      <div class="column column1">
        <div class="item item1">1</div>
        <div class="item item3">3</div>
      </div>
      <div class="column column2">
        <div class="item item2">2</div>
        <div class="item item4">4</div>
      </div>
    </main>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search