1

I'm learning responsive web-development using media queries and I want to know if it's possible to move an element from one div to another without using a script.

On a desktop display it's arranged like

      ---------
div1 |         | div2
div3 |  image  | div4
div5 |         | div6
      ---------

which is what I was going for.

and on mobile screens I want

      ---------
     |         | 
     |  image  |  
     |         |  
      ---------
         div1
         div2
         div3
         div4
         div5
         div6

But I can't seem to move divs past their parent divs.

HTML:

<!DOCTYPE html>

<html>
    <head>
        <meta charset = "UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Shuffle</title>
    </head>
    <body>
    
    <div class="header">
          <h1>Shuffle</h1>
    </div>    
          <div id="main">
                <div class="leftBox">
                       <div class="boxItem" id="first">
                                  <p>1</p>      
                       </div>
                       <div class="boxItem" id="third">
                                  <p>3</p>      
                       </div>   
                       <div class="boxItem" id="fifth">
                                  <p>5</p>              
                       </div>
                </div>
                <div class="image">
                        <img src="https://images.unsplash.com/photo-1605842581240-a0e2527d200b?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ">
                </div>
                <div class="rightBox">
                       <div class="boxItem" id="second">
                                  <p>2<p>
                       </div>
                       <div class="boxItem" id="fourth">
                                  <p>4</p>
                       </div>   
                       <div class="boxItem" id="sixth"> 
                                  <p>6</p>      
                       </div>
                </div>
        </div>
    </body>
</html>

CSS

/*
_______________________________________
          
          MOBILE SCREEN

_______________________________________
*/

* {
    box-sizing: border-box;
    font-family: "Comic Sans MS", Times, serif;
}

#main {
    display: -webkit-flex;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

html {
    text-align: center;
}

img{
    display: inline-block;
    max-width: 100%;
    height: auto;
}

.image {
    display: inline-block;
    width: auto;
    max-width: 50%;
    border: 1px solid gold;
    align-self:center;
     order: -1;    
}

.header {
    text-align: center;
}

.boxItem{
    border: 1px solid blue;
    padding: 2px;
    margin: 5px;
}

.leftBox{
    display: flex;
     flex-direction: column;
     width: 50%;
}

.rightBox{
    display: flex;
     flex-direction: column;
     width: 50%;
}

#first{
    order: 1;
}
#second{
    order: 2;
}
#third{
    order: 3;
}
#fourth{
    order: 4;
}
#fifth{
    order: 5;
}
#sixth{
    order: 6;
     
}

/*
_______________________________________
          
          DESKTOP SCREEN

_______________________________________
*/

@media only screen and (min-width: 768px) {
     
    #first{
        order: 1;
    }
    #second{
        order: 2;
    }
    #third{
        order: 3;
    }
    #fourth{
        order: 4;
    }
    #fifth{
        order: 5;
    }
    #sixth{
        order: 6;
    }     
  
     img{
          align-self: center;
     }
  
     .image{
          align-self: center;
          justify-content: center;
          align-items: center;   
          order: 0;    
     }
  
     #main{
          flex-direction: row;
          justify-content: space-between;
     }
  
     .leftBox{
          display:flex;
          flex-direction: column;
          justify-content: space-between;
          min-height: 100%;
          align-self: stretch;
     }
  
     .rightBox{
          display:flex;
          flex-direction: column;
          justify-content: space-between;
          min-height: 100%;
          align-self: stretch;
     }
}

If it's not possible to do this with css as it's written here, then is there another way to achieve this style using one flexbox?

I also have this on codepen https://codepen.io/johntarvis/pen/LYRYVmd?editors=1100 if that helps.

John Saville
  • 43
  • 1
  • 7

3 Answers3

1

You can do it like this. by using columns property and set it to 2. It's really difficult to achieve your approach without jquery. but in the image part you can set it to absolute and make it center part.

Here's a sample code.

.wrapper {
  position: relative;
  width: 100%;
  max-width: 1000px;
  margin: 0 auto;
  padding: 0;
}

#main {
  position: relative;
}

.column {
  -webkit-columns: 2;
  columns: 2;
  text-align: center;
  display: flex;
  justify-content: space-between;
  width: 100%;
  flex-wrap: wrap;
}

.sub_col {
  display: block;
  width: 34%;
  min-height: 100px;
  border: 1px solid red;
  margin: 0 0 1rem;
  position: relative;
  z-index: 15;
}

.image {
  width: 30%;
  margin: 0 auto;
  padding: 0;
  left: 0;
  right: 0;
  top: 50%;
  position: absolute;
  transform: translateY(-50%);
}

.image img {
  max-width: 100%;
}

@media only screen and (max-width:768px) {
  .column {
    -webkit-columns: 1;
    columns: 1;
  }
  .sub_col {
    width: 100%;
  }
  .image {
    top: 0;
    transform: none;
    margin-bottom: 1rem;
    position: relative;
    width: 100%;
  }
}
<div class="wrapper">
  <div id="main">

    <div class="image">
      <img src="https://images.unsplash.com/photo-1605842581240-a0e2527d200b?ixlib=rb-1.2.1&amp;q=85&amp;fm=jpg&amp;crop=entropy&amp;cs=srgb&amp;ixid=eyJhcHBfaWQiOjE0NTg5fQ">
    </div>

    <div class="column">
      <div class="sub_col">1</div>
      <div class="sub_col">2</div>
      <div class="sub_col">3</div>
      <div class="sub_col">4</div>
    </div>

  </div>
</div>

In this way your div elements are still in tact by numbering 1,2,3,4 and so on.

Jon P
  • 19,442
  • 8
  • 49
  • 72
laurence keith albano
  • 1,409
  • 4
  • 27
  • 59
  • Wow, you guys are fast and your code is so compact. I've got some studying to do. Yes, this was what I was looking for. Thank you. – John Saville Nov 27 '20 at 03:00
0

You can use @media queries and flexbox to achieve the desired result:

#main {
    display: flex;
    width: 100%;
    flex-direction: row;
    height: 300px;
}
#main > div { width: 33%;}
.leftBox, .rightBox {
    height: 100%; text-align: center;
    display: flex;        
    flex-direction: column;
    justify-content: center;
}    
img {max-width: 100%; height: auto;}
@media screen and (max-width: 768px) {
    #main {
        flex-direction: column;  
        height: auto;
    } 
    #main > div { width: 100%;}
    .image {order: -1;}
}
<div class="header">
        <h1>Shuffle</h1>
    </div>
    <div id="main">
        <div class="leftBox">
            <div class="boxItem" id="first">
                <p>1</p>
            </div>
            <div class="boxItem" id="third">
                <p>3</p>
            </div>
            <div class="boxItem" id="fifth">
                <p>5</p>
            </div>
        </div>
        <div class="image">
            <img src="https://images.unsplash.com/photo-1605842581240-a0e2527d200b?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ">
        </div>
        <div class="rightBox">
            <div class="boxItem" id="second">
                <p>2<p>
            </div>
            <div class="boxItem" id="fourth">
                <p>4</p>
            </div>
            <div class="boxItem" id="sixth">
                <p>6</p>
            </div>
        </div>
    </div>

Read more about ordering elements using flex on MDN

This SO related: how can I reorder HTML using media queries?

A. Meshu
  • 4,053
  • 2
  • 20
  • 34
0

CSS Grid might be the way to go.

You can maintain a more logical HTML ordering of 1 - 6 and use CSS to organize the display. This also avoids messing around with absolute positioning. The one downside is if you have a dynamic number of rows and want to span the image across all of them, in which case see this answer: https://stackoverflow.com/a/42240114/4665

You will only need to give minimal styling for mobile then replace the code in your desktop media query with the below. Then tweak the style as needed.

#main {
  /*Set Grid*/
  display: grid;
  /*We want 3 equal columns*/
  grid-template-columns: 1fr 1fr 1fr;
  /*And 3 equal rows -- Can be omitted*/
  grid-template-rows: 1fr 1fr 1fr;
  /*With a named area for the picture in the middle cell*/
  /*grid-template-areas: ". Pic ." ". Pic ." ". Pic .";*/
}


#main>.image {
  /*Place the image in column 2*/
  grid-column-start: 2;
  /*Place the image in the first row, span 3 rows*/
  grid-row: 1 / span 3;
  /*If Using named area, assign to the named area*/
  /*grid-area: Pic; */
}

/*Just for demo purposes, don't move this into your media query!*/
.image>img {
  width: 200px;
}

.boxItem {
  text-align: center;
}
<div class="header">
  <h1>Shuffle</h1>
</div>
<div id="main">

  <div class="image">
    <img src="https://images.unsplash.com/photo-1605842581240-a0e2527d200b?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ">
  </div>
  <div class="boxItem"><p>1</p></div>
  <div class="boxItem"><p>2</p></div>
  <div class="boxItem"><p>3</p></div>
  <div class="boxItem"><p>4</p></div>
  <div class="boxItem"><p>5</p></div>
  <div class="boxItem"><p>6</p></div>
</div>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Jon P
  • 19,442
  • 8
  • 49
  • 72