Nathaniel MacIver
Nathaniel MacIver

Reputation: 397

Rearrange DIV's from Side-Side to Top-Down in CSS

I'm looking to arrange an intranet page in a CSS Responsive manner. I'm trying to use @media breakpoints to rearrange four basic elements (nested in two divs) in the following manner:

@media only screen and (min-width: 1100px) /Desktop Mode/ enter image description here

@media only screen and (max-width: 1099px) /Mobile Devices/ enter image description here

I have gotten as far as I have using this code, which includes JQuery to add some gadgets into the individual Divs:

<script type="text/javascript">

var adhcal = '<iframe src="..."</iframe>'
var clincal = '<iframe src="..."</iframe>';
var timeUrl = '<iframe id = "timeTrack" src="...</iframe>';

function start()
{
 
 var dOne = $('<div>').addClass('divOne');
 var dTwo = $('<div>').addClass('divTwo');
 $('body').append(dOne).append(dTwo);
 
 
 var timeDiv = $('<div id = "timeDiv"></div>').addClass('timeDiv');
 dTwo.append(timeDiv);
 var timeTrack = $(timeUrl);
 timeDiv.append(timeTrack)
 timeTrack.load(function(){ 
 
 try{
    var timeHeight = document.getElementById('timeTrack').contentWindow.document;
    var body = timeHeight.body, html = timeHeight.documentElement;
    var height = Math.max( body.scrollHeight, body.offsetHeight, 
                           html.clientHeight, html.scrollHeight, html.offsetHeight);
      }
  catch(e){var height = 500;}
  
  timeDiv.height(height);});
 
 var adhDiv = $('<div id = "adhDiv"></div>').addClass('adhDiv');
 dTwo.append(adhDiv);
 adhcal = adhcal.replace('height="100%"', 'height="'+((adhDiv.height() > 0)?adhDiv.height():'600')+'"');
 adhDiv.append(adhcal);
 
 var clinDiv = $('<div id = "clinDiv"></div>').addClass('clinDiv');
 dTwo.append(clinDiv);
 clincal = clincal.replace('height="100%"', 'height="'+((clinDiv.height() > 0) ? clinDiv.height():'600')+'"');
 clinDiv.append(clincal);
 
 var postDiv = $('<div id = "postDiv"></div>').addClass('postDiv');
 dOne.append(postDiv);
 for(var p = 0; p < DATA.posts.length; p++)
 {
   postDiv.append('<h2>'+DATA.posts[p].title
   +'</h2><p class = "date">Published: '+moment(new Date(DATA.posts[p].date)).format('L')
   +'</p><p class="post">'
   +DATA.posts[p].html
   +'</p>').append('<hr>');
 }
 
}
</script>
<style>


.body{
   overflow:auto;
}
   H2{
    font-size: 2.00rem;
  font-family: 'Roboto', sans-serif;
  font-weight: 300;
      }
      
    .date{
    font-size: 1.00rem;
    color: #595959;
  font-family: 'Roboto', sans-serif;
  font-weight: 300;
    
    }   
    .post{
    font-size: 1.50rem;
  font-family: 'Roboto', sans-serif;
  font-weight: 300;
    
    }  

@media only screen and (min-width: 1100px) {
         
     .divOne{ 
           float:left;
           max-width:60%
            }

     .divTwo{
          float:right;
           max-width: 30%;
            }

    .adhDiv {
        max-width: 100%;
           height: 400px;

             }

    .clinDiv {
        max-width: 100%;
           height: 400px;  
    
             }

    .postDiv {
        max-width: 100%;
           height: 900px;
         overflow: auto;
         float: left;
             }

    .timeDiv {
       max-width: 100%;
          height: 200px;

             }
}

@media only screen and (max-width: 1099px){

     .divOne{ 

           display: flex;
            }

     .divTwo{
           position: absolute;
           top: 0;
           display: flex;
           width: 100%;
            }

    .adhDiv {
        max-width: 100%;
           height: 400px;

             }

    .clinDiv {
        max-width: 100%;
           height: 400px;  
    
             }

    .postDiv {
        max-width: 100%;
           height: 900px;
         overflow: auto;
         float: left;
             }

    .timeDiv {
       max-width: 100%;
          height: 200px;

             }
}

</style>
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script>var DATA = <?!= JSON.stringify(dataFromServerTemplate) ?>;</script>
    <?!= HtmlService.createHtmlOutputFromFile('CSS').getContent(); ?>
  </head>
  <body onload="start()">
   <?!= HtmlService.createHtmlOutputFromFile('JS-Intranet').getContent();?>
  </body>
</html>

At the moment, This code renders the way I want in Desktop mode, but under 1100px, the top half of the content in Div 2 will be cut off, as if it overlaps the top of the screen. Any other tricks I have tried just push Div 1 to the left of Div 2 and off of the screen. Can anyone see what I'm missing?

Thanks!

Upvotes: 1

Views: 2589

Answers (3)

Johannes
Johannes

Reputation: 67768

In your media query, add width: 100% to the first DIV and remove position: absolute from the second DIV.

Also, add flex-direction: column; to the second div to get the vertical stacking and flex-direction: column-reverse; to their container (whose class I made up below, but which has to wrap the two DIVs) to get the reversed order of DIVs when stacking:

.container {
   display: flex;
   flex-direction: column-reverse;
 }        
.divOne { 
   display: flex;
   width: 100%;            
}
.divTwo {
   display: flex;
   flex-direction: column;
   width: 100%;
}

Upvotes: 2

Nathaniel MacIver
Nathaniel MacIver

Reputation: 397

Thanks, Thomas. I tinkered around with your code and added some from a JS Fiddle to work out my solution below. I love it! Thanks!

<script type="text/javascript">

var adhcal =  '<iframe src="..."></iframe>';
var clincal = '<iframe src="..."></iframe>';
var timeUrl = '<iframe src="..."></iframe>';
var scoreImg = '<img width = "94%" src="...">';
function start()
{
 
 var dOne = $('<div>').addClass('divOne');
 var dTwo = $('<div>').addClass('divTwo');
 var container = $('<div>').addClass('container');
 container.append(dOne).append(dTwo);
 $('body').append(container);
 
 var timeDiv = $('<div id = "timeDiv"></div>').addClass('timeDiv');
 dTwo.append(timeDiv);
 var timeTrack = $(timeUrl);
 timeDiv.append(timeTrack)
 timeTrack.load(function(){ 
 
 try{
    var timeHeight = document.getElementById('timeTrack').contentWindow.document;
    var body = timeHeight.body, html = timeHeight.documentElement;
    var height = Math.max( body.scrollHeight, body.offsetHeight, 
                           html.clientHeight, html.scrollHeight, html.offsetHeight);
      }
  catch(e){var height = 500;}
  
  timeDiv.height(height);});
 
 var adhDiv = $('<div id = "adhDiv"></div>').addClass('adhDiv');
 dTwo.append(adhDiv);
 adhcal = adhcal.replace('height="100%"', 'height="'+((adhDiv.height() > 0)?adhDiv.height():'400')+'"');
 adhDiv.append(adhcal);
 
 var clinDiv = $('<div id = "clinDiv"></div>').addClass('clinDiv');
 dTwo.append(clinDiv);
 clincal = clincal.replace('height="100%"', 'height="'+((clinDiv.height() > 0) ? clinDiv.height():'400')+'"');
 clinDiv.append(clincal);
 
 var wrapDiv = $('<div id = "wrapDiv"></div>').addClass('wrapDiv');
 var postDiv = $('<div id = "postDiv"></div>').addClass('postDiv');
 wrapDiv.append('<H1>Blog Title</H1>').append(postDiv);
 dOne.append(wrapDiv);
 for(var p = 0; p < DATA.posts.length; p++)
 {
   postDiv.append('<h2>'+DATA.posts[p].title
   +'</h2><p class = "date">Published: '+moment(new Date(DATA.posts[p].date)).format('L')
   +'</p><p class="post">'
   +DATA.posts[p].html
   +'</p>').append('<hr>');
 }
 var scoreDiv = $('<div id = "scoreDiv"></div>').addClass('scoreDiv');
 dTwo.append(scoreDiv);
 scoreDiv.append(scoreImg);

}
</script>
<style>

   H2{
    font-size: 2.00rem;
  font-family: 'Roboto', sans-serif;
  font-weight: 300;
      }
   H1{
       font-size: 2.50rem;
       font-family: 'Roboto', sans-serif;
       font-weight: 325;
   }      
 .date{
    font-size: 1.00rem;
    color: #595959;
    font-family: 'Roboto', sans-serif;
    font-weight: 300;
    
    } 
    .post{
    font-size: 1.50rem;
    font-family: 'Roboto', sans-serif;
    font-weight: 300;
    }  
    

  .postDiv,  
    {
    margin:20em;
    overflow-y: hidden;
    overflow-x: hidden;
    }
    
  .timeDiv,
  .scoreDiv,{
     height: 400px;
     margin:2em;
     width: 100%;
           }
           
   .adhDiv,
  .clinDiv,
    {
     height: 200px;
     margin:2em;
     width: 100%;
    }

@media only screen and (min-width: 768px) {
  .container{
             width:98%;
            }
     .divOne{ 
           float: left;
           left:0;
           max-width:69%
            }
     .divTwo{
          float: right;
          max-width: 30%;
            }
   .wrapDiv {
           position: relative;
         max-height: 1200px;
            padding: 0;
             margin: 5% 5% 5% 5%;
          overflow-y: auto;
          overflow-x: hidden;
            }
}
@media only screen and (max-width: 767px) { 

  .container{
   width:100%;
   display:flex;
   flex-flow:row wrap;
   }
   .divOne{
     order:5;
     width:100%;
     background-color: #f9f9f9;
          }
          
   .divTwo{
     display: inline-block;
     width:100%;
           } 
  
  .postDiv
           {width: 100%}
  .timeDiv {  
  
  .wrapDiv {
   position: relative;
    max-height: 600px;
    padding: 0;
    margin: 5% 5% 5% 5%;
    overflow-y: auto;
    overflow-x: hidden;
}

     height: 400px;
     width: 100%;
           }
  .adhDiv,
  .clinDiv,
           {
     position: relative; padding-bottom: 75%; height: 0; overflow: hidden;
           }
}
</style>
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script>var DATA = <?!= JSON.stringify(dataFromServerTemplate) ?>;</script>
    <?!= HtmlService.createHtmlOutputFromFile('CSS').getContent(); ?>
  </head>
  <body onload="start()">
  <?!= HtmlService.createHtmlOutputFromFile('Scripts').getContent();?>
   <?!= HtmlService.createHtmlOutputFromFile('JS-Intranet').getContent();?>
  </body>
</html>

Upvotes: -1

Thomas Fellinger
Thomas Fellinger

Reputation: 656

This is a reduced showcase how it will work.

Also note that display:flex; will not work in all browsers - some of them provide vendor prefixes, check: http://caniuse.com/#search=flex and http://autoprefixer.github.io/

To learn more about flexbox, see here: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

.container{
  display:flex;
  flex-flow:row wrap;
  text-align:center; // only for code snippet, not needed when contents are there
}
.divOne{
  order:10;
  background:#F1D2E0;
  width:100%;
}
.divTwo{
  order:5;
  background:#C1E7CD;
  width:100%;
}
.adhDiv,
.clinDiv,
.postDiv,
.timeDiv {
  height: 400px;
  background:#C1DDE7;
  margin:2em;
}

@media only screen and (min-width: 1100px) {
  .divOne{
    flex:1;
    flex-basis: 60%;
    order:5;
  }
  .divTwo{
    flex:1;
    flex-basis: 40%;
    order:10;
  }
}
<div class="container">
  <div class="divOne">
    <h2>Div1</h2>
    <div class="postDiv">
      <h3>Post</h3>
    </div>
  </div>
  <div class="divTwo">
    <h2>Div2</h2>
    <div class="timeDiv">
      <h3>Time</h3>
    </div>
    <div class="adhDiv">
      <h3>Adh</h3>
    </div>
    <div class="clinDiv">
      <h3>Clin</h3>
    </div>
  </div>
</div>

Upvotes: 1

Related Questions