I'm making a responsive layout with a top fixed navbar. Underneath I have two columns, one for a sidebar (3), and one for content (9). Which on desktop looks like this
navbar
[3][9]
When I resize to mobile the navbar is compressed and hidden, then the sidebar is stacked on top of the content, like this:
navbar
[3]
[9]
I would like the main content at the top, so I need to change the order on mobile to this:
navbar
[9]
[3]
I found this article which covers the same points, but the accepted answer has been edited to say that the solution no applies to the current version of Bootstrap.
How can I reorder these columns on mobile? Or alternatively, how can I get the sidbar list-group into my expanding navbar?
Here is my code:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<div class="navbar navbar-inverse navbar-static-top">
<div class="container">
Brand Title
<button class="navbar-toggle" data-toggle="collapse" data-target=".navHeaderCollapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<div class="collapse navbar-collapse navHeaderCollapse">
<ul class="nav navbar-nav navbar-right"><!--original navbar-->
<li class="active">Home</li>
<li>FAQ</li>
</ul>
</div>
</div>
</div><!--End Navbar Div-->
<div class="container">
<div class="row">
<div class="col-lg-3">
<div class="list-group">
<a href="#" class="list-group-item">
<h4 class="list-group-item-heading">Lorem ipsum</h4>
<p class="list-group-item-text">Lorem Ipsum is simply dummy text.</p></a>
</div>
</div><!--end sidebar-->
<div class="col-lg-9">
<div class="panel panel-default">
<div class="panel-body">
<div class="page-header">
Main Content
</div>
</div>
</div><!--end main content area-->
You cannot change the order of columns in smaller screens but you can do that in large screens.
So change the order of your columns.
<!--Main Content-->
<div class="col-lg-9 col-lg-push-3">
</div>
<!--Sidebar-->
<div class="col-lg-3 col-lg-pull-9">
</div>
By default this displays the main content first.
So in mobile main content is displayed first.
By using col-lg-push and col-lg-pull we can reorder the columns in large screens and display sidebar on the left and main content on the right.
Working fiddle here.
Updated 2018
For the original question based on Bootstrap 3, the solution was to use push-pull.
In Bootstrap 4 it's now possible to change the order, even when the columns are full-width stacked vertically, thanks to Bootstrap 4 flexbox. OFC, the push pull method will still work, but now there are other ways to change column order in Bootstrap 4, making it possible to re-order full-width columns.
Method 1 - Use flex-column-reverse for xs screens:
<div class="row flex-column-reverse flex-md-row">
<div class="col-md-3">
sidebar
</div>
<div class="col-md-9">
main
</div>
</div>
Method 2 - Use order-first for xs screens:
<div class="row">
<div class="col-md-3">
sidebar
</div>
<div class="col-md-9 order-first order-md-last">
main
</div>
</div>
Bootstrap 4(alpha 6): http://www.codeply.com/go/bBMOsvtJhD
Bootstrap 4.1: https://www.codeply.com/go/e0v77yGtcr
Original 3.x Answer
For the original question based on Bootstrap 3, the solution was to use push-pull for the larger widths, and then the columns will show is their natural order on smaller (xs) widths. (A-B reverse to B-A).
<div class="container">
<div class="row">
<div class="col-md-9 col-md-push-3">
main
</div>
<div class="col-md-3 col-md-pull-9">
sidebar
</div>
</div>
</div>
Bootstrap 3: http://www.codeply.com/go/wgzJXs3gel
#emre stated, "You cannot change the order of columns in smaller screens but you can do that in large screens". However, this should be clarified to state: "You cannot change the order of full-width "stacked" columns.." in Bootstrap 3.
Bootstrap 3 Answer
The answers here work for just 2 cells, but as soon as those columns have more in them it can lead to a bit more complexity. I think I've found a generalized solution for any number of cells in multiple columns.
Goals
Get a vertical sequence of tags on mobile to arrange themselves in whatever order the design calls for on tablet/desktop. In this concrete example, one tag must enter flow earlier than it normally would, and another later than it normally would.
Mobile
[1 headline]
[2 image]
[3 qty]
[4 caption]
[5 desc]
Tablet+
[2 image ][1 headline]
[ ][3 qty ]
[ ][5 desc ]
[4 caption][ ]
[ ][ ]
So headline needs to shuffle right on tablet+, and technically, so does desc - it sits above the caption tag that precedes it on mobile. You'll see in a moment 4 caption is in trouble too.
Let's assume every cell could vary in height, and needs to be flush top-to-bottom with its next cell (ruling out weak tricks like a table).
As with all Bootstrap Grid problems step 1 is to realize the HTML has to be in mobile-order, 1 2 3 4 5, on the page. Then, determine how to get tablet/desktop to reorder itself in this way - ideally without Javascript.
The solution to get 1 headline and 3 qty to sit to the right not the left is to simply set them both pull-right. This applies CSS float: right, meaning they find the first open space they'll fit to the right. You can think of the browser's CSS processor working in the following order: 1 fits in to the right top corner. 2 is next and is regular (float: left), so it goes to top-left corner. Then 3, which is float: right so it leaps over underneath 1.
But this solution wasn't enough for 4 caption; because the right 2 cells are so short 2 image on the left tends to be longer than the both of them combined. Bootstrap Grid is a glorified float hack, meaning 4 caption is float: left. With 2 image occupying so much room on the left, 4 caption attempts to fit in the next available space - often the right column, not the left where we wanted it.
The solution here (and more generally for any issue like this) was to add a hack tag, hidden on mobile, that exists on tablet+ to push caption out, that then gets covered up by a negative margin - like this:
[2 image ][1 headline]
[ ][3 qty ]
[ ][4 hack ]
[5 caption][6 desc ^^^]
[ ][ ]
http://jsfiddle.net/b9chris/52VtD/16633/
HTML:
<div id=headline class="col-xs-12 col-sm-6 pull-right">Product Headline</div>
<div id=image class="col-xs-12 col-sm-6">Product Image</div>
<div id=qty class="col-xs-12 col-sm-6 pull-right">Qty, Add to cart</div>
<div id=hack class="hidden-xs col-sm-6">Hack</div>
<div id=caption class="col-xs-12 col-sm-6">Product image caption</div>
<div id=desc class="col-xs-12 col-sm-6 pull-right">Product description</div>
CSS:
#hack { height: 50px; }
#media (min-width: #screen-sm) {
#desc { margin-top: -50px; }
}
So, the generalized solution here is to add hack tags that can disappear on mobile. On tablet+ the hack tags allow displayed tags to appear earlier or later in the flow, then get pulled up or down to cover up those hack tags.
Note: I've used fixed heights for the sake of the simple example in the linked jsfiddle, but the actual site content I was working on varies in height in all 5 tags. It renders properly with relatively large variance in tag heights, especially image and desc.
Note 2: Depending on your layout, you may have a consistent enough column order on tablet+ (or larger resolutions), that you can avoid use of hack tags, using margin-bottom instead, like so:
Note 3: This uses Bootstrap 3. Bootstrap 4 uses a different grid set, and won't work with these examples.
http://jsfiddle.net/b9chris/52VtD/16632/
October 2017
I would like to add another Bootstrap 4 solution. One that worked for me.
The CSS "Order" property, combined with a media query, can be used to re-order columns when they get stacked in smaller screens.
Something like this:
#media only screen and (max-width: 768px) {
#first {
order: 2;
}
#second {
order: 4;
}
#third {
order: 1;
}
#fourth {
order: 3;
}
}
CodePen Link: https://codepen.io/preston206/pen/EwrXqm
Adjust the screen size and you'll see the columns get stacked in a different order.
I'll tie this in with the original poster's question. With CSS, the navbar, sidebar, and content can be targeted and then order properties applied within a media query.
In Bootstrap 4, if you want to do something like this:
Mobile | Desktop
-----------------------------
A | A
C | B C
B | D
D |
You need to reverse the order of B then C then apply order-{breakpoint}-first to B. And apply two different settings, one that will make them share the same cols and other that will make them take the full width of the 12 cols:
Smaller screens: 12 cols to B and 12 cols to C
Larger screens: 12 cols between the sum of them (B + C = 12)
Like this
<div class='row no-gutters'>
<div class='col-12'>
A
</div>
<div class='col-12'>
<div class='row no-gutters'>
<div class='col-12 col-md-6'>
C
</div>
<div class='col-12 col-md-6 order-md-first'>
B
</div>
</div>
</div>
<div class='col-12'>
D
</div>
</div>
Demo: https://codepen.io/anon/pen/wXLGKa
Starting with the mobile version first, you can achieve what you want, most of the time.
Examples here:
http://jsbin.com/wulexiq/edit?html,css,output
<div class="container">
<h1>PUSH - PULL Bootstrap demo</h1>
<h2>Version 1:</h2>
<div class="row">
<div class="col-xs-12 col-sm-5 col-sm-push-3 green">
IN MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
<hr> TOP ROW XS-SMALL SCREEN
</div>
<div class="col-xs-12 col-sm-4 col-sm-push-3 gold">
TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
<hr> MIDDLE ROW ON XS-SMALL
</div>
<div class="col-xs-12 col-sm-3 col-sm-pull-9 red">
TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN
<hr> BOTTOM ROW ON XS-SMALL
</div>
</div>
<h2>Version 2:</h2>
<div class="row">
<div class="col-xs-12 col-sm-4 col-sm-push-8 yellow">
TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
<hr> TOP ROW ON XS-SMALL
</div>
<div class="col-xs-12 col-sm-4 col-sm-pull-4 blue">
TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN
<hr> MIDDLE ROW XS-SMALL SCREEN
</div>
<div class="col-xs-12 col-sm-4 col-sm-pull-4 pink">
IN MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
<hr> BOTTOM ROW ON XS-SMALL
</div>
</div>
<h2>Version 3:</h2>
<div class="row">
<div class="col-xs-12 col-sm-5 cyan">
TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN TOP ROW ON XS-SMALL
</div>
<div class="col-xs-12 col-sm-3 col-sm-push-4 orange">
TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
<hr> MIDDLE ROW ON XS-SMALL
</div>
<div class="col-xs-12 col-sm-4 col-sm-pull-3 brown">
IN THE MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
<hr> BOTTOM ROW XS-SMALL SCREEN
</div>
</div>
<h2>Version 4:</h2>
<div class="row">
<div class="col-xs-12 col-sm-4 col-sm-push-8 darkblue">
TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
<hr> TOP ROW XS-SMALL SCREEN
</div>
<div class="col-xs-12 col-sm-4 beige">
MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
<hr> MIDDLE ROW ON XS-SMALL
</div>
<div class="col-xs-12 col-sm-4 col-sm-pull-8 silver">
TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN
<hr> BOTTOM ROW ON XS-SMALL
</div>
</div>
</div>
This is quite easy with jQuery using insertAfter() or insertBefore():
<div class="left">content</div>
<div class="right">sidebar</div>
<script>
$('.right').insertBefore('left');
</script>
If you want to to set o condition for mobile devices you can make it like this:
<script>
var $iW = $(window).innerWidth();
if ($iW < 992){
$('.right').insertBefore('.left');
}else{
$('.right').insertAfter('.left');
}
</script>
example
https://jsfiddle.net/w9n27k23/
Its very simple, write your html the way you would want it to be viewed in mobile. Then using the bootstrap order class you can arrange how you want it to viewed on desktop.
<html>
<head>
<title>Order View</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
<div class="row">
<div class="col order-md-2">
<h1>IMAGE</h1>
</div>
<div class="col order-md-1">
<h1>TEXT</h1>
</div>
</body>
</html>
Related
guys. I have a little problem here working with bootstrap. I am trying to make a div container with a row containing 3 columns equally proportioned in width :
<div class="row">
<div class="col-md-4" style="background:red;">logo</div>
<div class="col-md-4" style="background:blue;">content</div>
<div class="col-md-4" style="background:yellow;">content+imgs</div>
</div>
</div>
The problem I have is that I want the column with 'logo' to be the second one (after 'content') on xs/sm devices or at resizing the browser window. I tried with push and pull, but I want the columns to be one above each other, not inline, as at the md devices. I have no clue how to do that, any help? :)
Using order classes with bootstrap, you can change the order of the columns responsively.
This example will put the second column first on XS and SM screens.
<!--bootstrap 4-->
<div class="row">
<div class="col-md-4 order-2 order-md-1">first</div>
<div class="col-md-4 order-1 order-md-2">second</div>
<div class="col-md-4 order-3 order-md-3">third</div>
</div>
edit:
For bootstrap 3 (3.3.7) you will need to use push & pull classes. In your case, you would have to make the logo the second column. Mobile counts as the starting point in bootstrap development.
<!-- bootstrap 3 -->
<div class="row">
<div class="col-md-4 col-md-push-4" style="background-color:red;">content</div>
<div class="col-md-4 col-md-pull-4" style="background-color:blue;">logo</div>
<div class="col-md-4" style="background-color:yellow;">content+imgs</div>
</div>
I have 3 divs inside one div horizontally aligned.
| 1 | 2 | 3 |
In smaller devices, I want 3 to move to under 1 and look like this:
| 1 | 2 |
| 3 | 2 |
I can do that creating different layouts maybe, but is there anyway to do in bootstrap using grids?
EDIT
Here is a demonstration of what I want to achieve. In desktop, I want it to look like this:
In Mobile:
Demo
HTML:
<div class="col-xs-4 col-sm-4" style="height:100px;background:red;">A</div>
<div class="col-xs-8 col-sm-4 float" style="height:100px;background:blue">B</div>
<div class="col-xs-4 col-sm-4" style="height:100px;background:green">C</div>
CSS:
#media (max-width: 768px)
{
.float
{
float:right!important;
height:200px!important;
}
}
Yes you can do it via col-sm-push and col-sm-pull similar post;
Column order manipulation using col-lg-push and col-lg-pull in Twitter Bootstrap 3
Also check a much detail post here.
I'm assuming you want the 3rd box to be directly below the 1st box while the 2nd box is higher than the 1st box. This can only be achieved in Bootstrap by duplicating the contents of the 3rd box and hiding/showing it based on the grid size (e.g. sm). Pushing or pulling columns, using e.g. col-sm-push-4, won't help as they'll never make a column wrap to the next line.
As Bootstrap is a mobile first framework, the first step is to create the small layout. In order to get the 3rd box directly below the 1st box we'll need to use column nesting. The idea is to put the 1st and 3rd box in an inner grid inside the left column of the outer grid, while the 2nd box will be put in right column of the outer grid. Notice that the inner grid needs a .row to offset the padding of its parents col-xs-6, and that the columns inside the inner grid count up to 12. Some people think it needs to count up to 6 as they exist inside a col-xs-6, but that isn't the case.
<div class="container">
<div class="row">
<div class="col-xs-6">
<div class="row">
<div class="col-xs-12">
<div class="box box--one">One</div>
</div>
<div class="col-xs-12">
<div class="box box--three">Three</div>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="box box--two">Two</div>
</div>
</div>
</div>
The small layout now looks good. To get the other layout (I've assumed md as its breakpoint) change both col-xs-6 to col-xs-6 col-md-4 and add a 3rd column to the outer grid containing the 3rd box.
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-4">
...
</div>
<div class="col-xs-6">
...
</div>
<div class="col-md-4">
<div class="box box--three">Three</div>
</div>
</div>
</div>
It now looks completely broken, the 3rd box is shown twice and one of them is overlapping the 1st and 2nd box on screens smaller than md. We can fix this by hiding the columns containing the 3rd box for specific grid sizes. To hide the 3rd box inside the inner grid for larger screens change <div class="col-sm-12"> into <div class="col-sm-12 hidden-md hidden-lg">. And to hide the 3rd outer column for smaller screens change <div class="col-md-4"> into <div class="col-md-4 hidden-xs hidden-sm">
See the entire example code below:
.box {
border: 1px solid #c66;
background-color: #f99;
padding: 15px;
color: #fff;
font-family: Helvetica, Arial;
font-size: 24px;
}
.box--one,
.box--three {
height: 100px;
}
.box--two {
height: 200px;
}
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-4">
<div class="row">
<div class="col-xs-12">
<div class="box box--one">One</div>
</div>
<div class="col-xs-12 hidden-md hidden-lg">
<div class="box box--three">Three</div>
</div>
</div>
</div>
<div class="col-xs-6 col-md-4">
<div class="box box--two">Two</div>
</div>
<div class="col-md-4 hidden-xs hidden-sm">
<div class="box box--three">Three</div>
</div>
</div>
</div>
PS If you don't like duplicating the 3rd box, as perhaps there's a lot of content inside, you can also use JavaScript to move the box into it's proper column when a breakpoint change occurs. I've made some jQuery plugin prototype that should be able to do this, see https://github.com/ckuijjer/jquery-breakpointspy
PS I just saw your updated question: if the boxes have a fixed height, simply add a class to the 3rd box of the large layout that gets a fixed height. If they don't have a fixed height, create some JavaScript that set the height to be equal and attach it to the resize event. A completely different solution would be to look into flexbox.
Good day! I am trying to figure out if the scenario below is possible.
When it is on desktop/laptop the layout should be like this
<div class="col-md-3">
sidebar
</div>
<div class="col-md-9">
article
</div>
When it is on small screen the two div will switch and must be like this one
<div class="col-md-9">
sidebar
</div>
<div class="col-md-3">
article
</div>
Your answer is appreciated!
You can! By adding multiple grid classes to your <div>'s you can define the size of your columns for each breakpoint. In your case this might be col-xs-9 col-md-3 on the sidebar and col-xs-3 col-md-9 on the article. This would make the sidebar take up 9 out of 12 columns for the xs and sm breakpoint sizes, and 3 out of 12 columns for the md and lg breakpoint sizes.
Open the following example in fullscreen to play with the breakpoints.
.box {
border: 1px solid #c66;
background-color: #f99;
}
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="col-xs-9 col-md-3 box">
sidebar
</div>
<div class="col-xs-3 col-md-9 box">
article
</div>
From your comment I see you want the article to be on top of the sidebar for small screens. This is a bit more tricky. You need to do three things:
Develop mobile first by starting with the layout for small screens. You need to change the order of the sidebar and article <div>.
Make sure that on small screens both the sidebar and the article take up 12 out of 12 columns by using col-xs-12. This will make the sidebar get pushed below the article.
Note that on desktop screens the sidebar and article do appear next to eachother, but with the sidebar on the right instead of the left. You can change this by pulling the sidebar to the left by adding col-md-pull-9 (you need to pull it 9 columns to the left, the amount of columns that the article takes up) and pushing the article to the right by adding col-md-push-3 (you need to push it 3 columns to the right, the amount of columns that the sidebar takes up).
See the updated example:
.box {
border: 1px solid #c66;
background-color: #f99;
}
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="col-xs-12 col-md-9 col-md-push-3 box">
article
</div>
<div class="col-xs-12 col-md-3 col-md-pull-9 box">
sidebar
</div>
There is few prefixes for bootstrap to specify width class: -xs- / -sm- / -md- / -lg- (from smallest to biggest width).
So from -md- and bigger screen you have col-md-3 and col-md-9. To get them in reverse order on pre--md- class you can specify -xs- or -sm- prefix.
So to reverse your classes, just write:
<div class="col-md-9 col-xs-3"></div>
<div class="col-md-3 col-xs-9"></div>
Try this:
<div class="col-sm-9 col-md-3">
sidebar
</div>
<div class="col-sm-3 col-md-9">
article
</div>
This will display the sidebar in 9 blocks in eXtraSmall (xs) and SMall (sm) and in 3 Blocks for MeDium (md) and LarGe (lg) and vice versa.
I have a Bootstrap Page like this:
<div class="row">
<div class="col-md-6">
A
</div>
<div class="col-md-6">
B
</div>
</div>
Looks like:
-----
|A|B|
-----
So if I look at it on a mobile Device, the Column A is on top, but I want the B on top.
Is this possible?
I tried it with push an pull, but it didn't work.
Use Column ordering to accomplish this.
col-md-push-6 will "push" the column to the right 6 and col-md-pull-6 will "pull" the column to the left on "md" or greater view-ports. On any smaller view-ports the columns will be in normal order again.
I think what throws people off, is that you have to put B above A in your HTML. There may be a different way to do this where A can go above B in the HTML, but I'm not sure how to do it...
DEMO
<div class="row">
<div class="col-md-6 col-md-push-6">B</div>
<div class="col-md-6 col-md-pull-6">A</div>
</div>
view-port >= md
|A|B|
view-port < md
|B|
|A|
It's worth noting that if you are using columns that are not both equal to 6, then the push amount will not equal the initial column size.
If you have 2 columns (A & B) and wish for column A to be smaller and to the right on "sm" or greater viewports, but atop a mobile (xs) viewport, you would use the following:
<div class="row">
<div class="col-sm-4 col-sm-push-8">A</div>
<div class="col-sm-8 col-sm-pull-4">B</div>
</div>
Otherwise, the alignment of the columns will appear off.
Flexbox Direction
For Bootstrap 4, apply one of the following to your .row div:
.flex-row-reverse
For responsive settings:
.flex-sm-row-reverse
.flex-md-row-reverse
.flex-lg-row-reverse
.flex-xl-row-reverse
In Bootstrap 4, let's say you want to have one order for large screens and a different order for smaller screens:
<div class="container">
<div class="row">
<div class="col-6 order-1 order-lg-2">
This column will be ordered second on large to extra large screens
</div>
<div class="col-6 order-2 order-lg-1">
This column will be ordered first on large to extra large screens
</div>
</div>
</div>
You can omit order-1 and order-2 above. Just added for clarity. Default order will be the order the columns appear in the html.
For more info https://getbootstrap.com/docs/4.1/layout/grid/#reordering
The below code work for me
.row {
display: flex;
flex-direction: column-reverse;
}
This is now done (in Bootstrap v4) by adding order-# classes.
See https://getbootstrap.com/docs/4.1/migration/#grid-system-1
Like this:
<div classname='col-md-8 order-2'>...</div>
<div classname='col-md-4 order-1'>...</div>
I have three bootstrap 4 columns of different sizes. As the screen gets smaller the third column is hidden, then when the screen gets smaller still and the divs are stacked the order changes so that column 2 is at the top.
<div class="col-xs-12 col-sm-4 col-md-3 order-2 order-sm-1">
<h3>LEFT HAND SECTION</h3>
<p>For news, links photos or comments.</p>
</div>
<div class="col-xs-12 col-sm-8 col-md-5 order-1 order-sm-2">
<h3>MAIN SECTION</h3>
<p>The main content for the page.</p>
</div>
<div class="col-xs-12 col-md-4 d-none d-md-block order-last">
<h3>BLANK SECTION</h3>
<p>Will usually just be blank.</p>
</div>
I hope this helps. I found it difficult to understand this but finally got there with the help of this thread, but it was a bit hit and miss.
I used:
.row {
display: flex;
flex-direction: row-reverse;
}
This worked for me on Bootstrap 4:
<div class="container-fluid">
<div class="row">
<div class="col-md-4 order-md-last">
<%= render 'form'%>
</div>
<div class="col-md-8 order-md-first">
CONTENT
</div>
</div>
</div>
Bootstrap 4 includes classes for flex.
See: https://getbootstrap.com/docs/4.3/layout/utilities-for-layout/
<div class="row flex-column-reverse flex-md-row">
<div class="col-sm-10">
Col 1
</div>
<div class="col-sm-2">
Col 2
</div>
</div>
In Bootstrap V4 (Released January 18, 2018) You can use Reordering Classes. Info here under Reordering tab.
https://getbootstrap.com/docs/4.0/layout/grid/
I'm making a responsive layout with a top fixed navbar. Underneath I have two columns, one for a sidebar (3), and one for content (9). Which on desktop looks like this
navbar
[3][9]
When I resize to mobile the navbar is compressed and hidden, then the sidebar is stacked on top of the content, like this:
navbar
[3]
[9]
I would like the main content at the top, so I need to change the order on mobile to this:
navbar
[9]
[3]
I found this article which covers the same points, but the accepted answer has been edited to say that the solution no applies to the current version of Bootstrap.
How can I reorder these columns on mobile? Or alternatively, how can I get the sidbar list-group into my expanding navbar?
Here is my code:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<div class="navbar navbar-inverse navbar-static-top">
<div class="container">
Brand Title
<button class="navbar-toggle" data-toggle="collapse" data-target=".navHeaderCollapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<div class="collapse navbar-collapse navHeaderCollapse">
<ul class="nav navbar-nav navbar-right"><!--original navbar-->
<li class="active">Home</li>
<li>FAQ</li>
</ul>
</div>
</div>
</div><!--End Navbar Div-->
<div class="container">
<div class="row">
<div class="col-lg-3">
<div class="list-group">
<a href="#" class="list-group-item">
<h4 class="list-group-item-heading">Lorem ipsum</h4>
<p class="list-group-item-text">Lorem Ipsum is simply dummy text.</p></a>
</div>
</div><!--end sidebar-->
<div class="col-lg-9">
<div class="panel panel-default">
<div class="panel-body">
<div class="page-header">
Main Content
</div>
</div>
</div><!--end main content area-->
You cannot change the order of columns in smaller screens but you can do that in large screens.
So change the order of your columns.
<!--Main Content-->
<div class="col-lg-9 col-lg-push-3">
</div>
<!--Sidebar-->
<div class="col-lg-3 col-lg-pull-9">
</div>
By default this displays the main content first.
So in mobile main content is displayed first.
By using col-lg-push and col-lg-pull we can reorder the columns in large screens and display sidebar on the left and main content on the right.
Working fiddle here.
Updated 2018
For the original question based on Bootstrap 3, the solution was to use push-pull.
In Bootstrap 4 it's now possible to change the order, even when the columns are full-width stacked vertically, thanks to Bootstrap 4 flexbox. OFC, the push pull method will still work, but now there are other ways to change column order in Bootstrap 4, making it possible to re-order full-width columns.
Method 1 - Use flex-column-reverse for xs screens:
<div class="row flex-column-reverse flex-md-row">
<div class="col-md-3">
sidebar
</div>
<div class="col-md-9">
main
</div>
</div>
Method 2 - Use order-first for xs screens:
<div class="row">
<div class="col-md-3">
sidebar
</div>
<div class="col-md-9 order-first order-md-last">
main
</div>
</div>
Bootstrap 4(alpha 6): http://www.codeply.com/go/bBMOsvtJhD
Bootstrap 4.1: https://www.codeply.com/go/e0v77yGtcr
Original 3.x Answer
For the original question based on Bootstrap 3, the solution was to use push-pull for the larger widths, and then the columns will show is their natural order on smaller (xs) widths. (A-B reverse to B-A).
<div class="container">
<div class="row">
<div class="col-md-9 col-md-push-3">
main
</div>
<div class="col-md-3 col-md-pull-9">
sidebar
</div>
</div>
</div>
Bootstrap 3: http://www.codeply.com/go/wgzJXs3gel
#emre stated, "You cannot change the order of columns in smaller screens but you can do that in large screens". However, this should be clarified to state: "You cannot change the order of full-width "stacked" columns.." in Bootstrap 3.
Bootstrap 3 Answer
The answers here work for just 2 cells, but as soon as those columns have more in them it can lead to a bit more complexity. I think I've found a generalized solution for any number of cells in multiple columns.
Goals
Get a vertical sequence of tags on mobile to arrange themselves in whatever order the design calls for on tablet/desktop. In this concrete example, one tag must enter flow earlier than it normally would, and another later than it normally would.
Mobile
[1 headline]
[2 image]
[3 qty]
[4 caption]
[5 desc]
Tablet+
[2 image ][1 headline]
[ ][3 qty ]
[ ][5 desc ]
[4 caption][ ]
[ ][ ]
So headline needs to shuffle right on tablet+, and technically, so does desc - it sits above the caption tag that precedes it on mobile. You'll see in a moment 4 caption is in trouble too.
Let's assume every cell could vary in height, and needs to be flush top-to-bottom with its next cell (ruling out weak tricks like a table).
As with all Bootstrap Grid problems step 1 is to realize the HTML has to be in mobile-order, 1 2 3 4 5, on the page. Then, determine how to get tablet/desktop to reorder itself in this way - ideally without Javascript.
The solution to get 1 headline and 3 qty to sit to the right not the left is to simply set them both pull-right. This applies CSS float: right, meaning they find the first open space they'll fit to the right. You can think of the browser's CSS processor working in the following order: 1 fits in to the right top corner. 2 is next and is regular (float: left), so it goes to top-left corner. Then 3, which is float: right so it leaps over underneath 1.
But this solution wasn't enough for 4 caption; because the right 2 cells are so short 2 image on the left tends to be longer than the both of them combined. Bootstrap Grid is a glorified float hack, meaning 4 caption is float: left. With 2 image occupying so much room on the left, 4 caption attempts to fit in the next available space - often the right column, not the left where we wanted it.
The solution here (and more generally for any issue like this) was to add a hack tag, hidden on mobile, that exists on tablet+ to push caption out, that then gets covered up by a negative margin - like this:
[2 image ][1 headline]
[ ][3 qty ]
[ ][4 hack ]
[5 caption][6 desc ^^^]
[ ][ ]
http://jsfiddle.net/b9chris/52VtD/16633/
HTML:
<div id=headline class="col-xs-12 col-sm-6 pull-right">Product Headline</div>
<div id=image class="col-xs-12 col-sm-6">Product Image</div>
<div id=qty class="col-xs-12 col-sm-6 pull-right">Qty, Add to cart</div>
<div id=hack class="hidden-xs col-sm-6">Hack</div>
<div id=caption class="col-xs-12 col-sm-6">Product image caption</div>
<div id=desc class="col-xs-12 col-sm-6 pull-right">Product description</div>
CSS:
#hack { height: 50px; }
#media (min-width: #screen-sm) {
#desc { margin-top: -50px; }
}
So, the generalized solution here is to add hack tags that can disappear on mobile. On tablet+ the hack tags allow displayed tags to appear earlier or later in the flow, then get pulled up or down to cover up those hack tags.
Note: I've used fixed heights for the sake of the simple example in the linked jsfiddle, but the actual site content I was working on varies in height in all 5 tags. It renders properly with relatively large variance in tag heights, especially image and desc.
Note 2: Depending on your layout, you may have a consistent enough column order on tablet+ (or larger resolutions), that you can avoid use of hack tags, using margin-bottom instead, like so:
Note 3: This uses Bootstrap 3. Bootstrap 4 uses a different grid set, and won't work with these examples.
http://jsfiddle.net/b9chris/52VtD/16632/
October 2017
I would like to add another Bootstrap 4 solution. One that worked for me.
The CSS "Order" property, combined with a media query, can be used to re-order columns when they get stacked in smaller screens.
Something like this:
#media only screen and (max-width: 768px) {
#first {
order: 2;
}
#second {
order: 4;
}
#third {
order: 1;
}
#fourth {
order: 3;
}
}
CodePen Link: https://codepen.io/preston206/pen/EwrXqm
Adjust the screen size and you'll see the columns get stacked in a different order.
I'll tie this in with the original poster's question. With CSS, the navbar, sidebar, and content can be targeted and then order properties applied within a media query.
In Bootstrap 4, if you want to do something like this:
Mobile | Desktop
-----------------------------
A | A
C | B C
B | D
D |
You need to reverse the order of B then C then apply order-{breakpoint}-first to B. And apply two different settings, one that will make them share the same cols and other that will make them take the full width of the 12 cols:
Smaller screens: 12 cols to B and 12 cols to C
Larger screens: 12 cols between the sum of them (B + C = 12)
Like this
<div class='row no-gutters'>
<div class='col-12'>
A
</div>
<div class='col-12'>
<div class='row no-gutters'>
<div class='col-12 col-md-6'>
C
</div>
<div class='col-12 col-md-6 order-md-first'>
B
</div>
</div>
</div>
<div class='col-12'>
D
</div>
</div>
Demo: https://codepen.io/anon/pen/wXLGKa
Starting with the mobile version first, you can achieve what you want, most of the time.
Examples here:
http://jsbin.com/wulexiq/edit?html,css,output
<div class="container">
<h1>PUSH - PULL Bootstrap demo</h1>
<h2>Version 1:</h2>
<div class="row">
<div class="col-xs-12 col-sm-5 col-sm-push-3 green">
IN MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
<hr> TOP ROW XS-SMALL SCREEN
</div>
<div class="col-xs-12 col-sm-4 col-sm-push-3 gold">
TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
<hr> MIDDLE ROW ON XS-SMALL
</div>
<div class="col-xs-12 col-sm-3 col-sm-pull-9 red">
TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN
<hr> BOTTOM ROW ON XS-SMALL
</div>
</div>
<h2>Version 2:</h2>
<div class="row">
<div class="col-xs-12 col-sm-4 col-sm-push-8 yellow">
TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
<hr> TOP ROW ON XS-SMALL
</div>
<div class="col-xs-12 col-sm-4 col-sm-pull-4 blue">
TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN
<hr> MIDDLE ROW XS-SMALL SCREEN
</div>
<div class="col-xs-12 col-sm-4 col-sm-pull-4 pink">
IN MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
<hr> BOTTOM ROW ON XS-SMALL
</div>
</div>
<h2>Version 3:</h2>
<div class="row">
<div class="col-xs-12 col-sm-5 cyan">
TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN TOP ROW ON XS-SMALL
</div>
<div class="col-xs-12 col-sm-3 col-sm-push-4 orange">
TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
<hr> MIDDLE ROW ON XS-SMALL
</div>
<div class="col-xs-12 col-sm-4 col-sm-pull-3 brown">
IN THE MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
<hr> BOTTOM ROW XS-SMALL SCREEN
</div>
</div>
<h2>Version 4:</h2>
<div class="row">
<div class="col-xs-12 col-sm-4 col-sm-push-8 darkblue">
TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
<hr> TOP ROW XS-SMALL SCREEN
</div>
<div class="col-xs-12 col-sm-4 beige">
MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
<hr> MIDDLE ROW ON XS-SMALL
</div>
<div class="col-xs-12 col-sm-4 col-sm-pull-8 silver">
TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN
<hr> BOTTOM ROW ON XS-SMALL
</div>
</div>
</div>
This is quite easy with jQuery using insertAfter() or insertBefore():
<div class="left">content</div>
<div class="right">sidebar</div>
<script>
$('.right').insertBefore('left');
</script>
If you want to to set o condition for mobile devices you can make it like this:
<script>
var $iW = $(window).innerWidth();
if ($iW < 992){
$('.right').insertBefore('.left');
}else{
$('.right').insertAfter('.left');
}
</script>
example
https://jsfiddle.net/w9n27k23/
Its very simple, write your html the way you would want it to be viewed in mobile. Then using the bootstrap order class you can arrange how you want it to viewed on desktop.
<html>
<head>
<title>Order View</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
<div class="row">
<div class="col order-md-2">
<h1>IMAGE</h1>
</div>
<div class="col order-md-1">
<h1>TEXT</h1>
</div>
</body>
</html>