1

The mobile and tablet layout for this grid is as follows:

[Header]

[Image]

[Content]

However, in medium/larger screen, I would like to change it to this layout

enter image description here

The code snippet below is created with mobile first so that it can be reordered in large screens. But the content column is not right below the header in medium/larger screens. The content column should fill the remaining height.

How to get this to the desired layout? If it is not possible by bootstrap, can I use flexbox?

.tall {
  height: 150px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.2.0/sandstone/bootstrap.min.css" rel="stylesheet"/>
<div class="container text-center">
  <div class="row"> 
    <div class="col-sm-12">
      <h4>Reorder columns in larger display</h4>
      <div class="row"> 
        <div class="col-xs-12 col-sm-12 col-md-6 col-md-push-6">
          <div class="well">Header</div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-6 col-md-pull-6">
          <div class="well tall">Image</div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-6 col-md-push-6">
          <div class="well">Content</div>
        </div>
      </div>    
    </div>
  </div>
</div>
Goku
  • 15
  • 1
  • 3

2 Answers2

1

You cannot do this directly in bootstrap.You need to move content div next to the header div based on the size of the screen. This cannot be done as css cannot move the div around html.

1.One solution is to use jquery to move the div on change in size.See the code sample below.But this might cause performance issues because it will check the criteria whenever the screen is resized.

<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.2.0/sandstone/bootstrap.min.css" rel="stylesheet"/>
<script src="http://code.jquery.com/jquery-3.2.1.min.js" type="application/javascript"></script>
<script type="application/javascript">
    function moveDiv(){
        if($(window).width() > 990 ){ // screen size 
            $("#content").insertAfter("#header"); //insert after header div
        }else{
            $("#content").appendTo("#contentbox"); // append it as child to contentbox
        }
    }
    $(document).ready(function () {
        moveDiv();// default check whenever page loads
        $(window).resize(function(){
         moveDiv(); // on resize check
        });
    });
</script>
<div class="container text-center">
<div class="row">
    <div class="col-sm-12">
        <h4>Reorder columns in larger display</h4>
        <div class="row">
            <div id="headerbox" class="col-xs-12 col-sm-12 col-md-6 col-md-push-6">
                <div id="header" class="well">Header</div>
            </div>
            <div class="col-xs-12 col-sm-12 col-md-6 col-md-pull-6">
                <div class="well tall">Image</div>
            </div>

            <div id="contentbox" class="col-xs-12 col-sm-12 col-md-6 col-md-push-6">
                <div id="content" class="well">Content</div>
            </div>

        </div>
    </div>
</div>

  1. You can use visible , invisible criteria on div but you should introduce same div twice ,if you need to maintain the structure.This is a quick hack, but the div should be repeated to maintain the structure.(EDIT: Refer post by lamelemon)

  2. This is something new to consider. Try using grid layouts in css which was recently introduced. Whatever you have explained can be done with few lines of code only using css. https://css-tricks.com/snippets/css/complete-guide-grid/ and check out this youtube video https://www.youtube.com/watch?v=3vJE3bVoF-Q for demo of grid

If you are not using using bootstrap you can do this with regular css like I explained in code snippet.But you have to handle compatibility with older browser.

.tall {
  height: 150px;
}

.divborder {
  border: hidden;
  margin: 1em;
  background-color: grey;
}

@supports (display: grid) /*If browser supports grid*/  {

 /*default div is displayed one by one*/
 
 /*for bigger screen sizes*/
  @media all and (min-width: 600px) {
    .box { /* grid container*/
      display: grid;
      grid-template-columns: 1fr 1fr; /*Specify number of columns 1fr is one fraction of screen*/
      grid-template-rows: 1fr 1fr; /*Specify number of rows*/
    }
    .header {
      grid-row: 1/2; /*start from 1 and end at 2 */
      grid-column: 2/-1; /*start from 2 and end of box (left to right edge)*/
    }
    .image {
      grid-row: 1/-1; /*top to bottom of row*/
      grid-column: 1/2
    }
    .content {
      grid-row: 2/-1;
      grid-column: 2/-1;
    }
  }
}
/*Code for backward compatability*/
<h4>Reorder columns in larger display</h4>
<div class="box">
  <div id="header" class="header divborder">Header</div>
  <div class="image tall divborder">Image</div>
  <div id="content" class="content well divborder">Content</div>
</div>
0

I don't think you can accomplish this out of the box with bootstrap without the whitespace unless your content fills it but what you could do since it's just an image is load the image in both spots and hide and show depending on the screen size with .visible-* and .hidden-*.

.tall {height: 150px;}
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.2.0/sandstone/bootstrap.min.css" rel="stylesheet"/>
<div class="container text-center">
  <div class="row"> 
    <div class="col-sm-12">
      <h4>Reorder columns in larger display</h4>
      <div class="row"> 
         <div class="col-xs-12 col-sm-12 col-md-6 hidden-sm hidden-xs">
          <div class="well tall">Image</div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-6">
          <div class="well">Header</div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-6 visible-sm visible-xs">
          <div class="well tall">Image</div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-6">
          <div class="well">Content</div>
        </div>
      </div>    
    </div>
  </div>
</div>
Steven B.
  • 8,962
  • 3
  • 24
  • 45
  • 1
    Thank you. But I just used your hack on the header div with visible and hidden. I think it is less load compared to two images! – Goku Aug 01 '17 at 19:58