If you open up the unminified CSS for Bootstrap, which is second best way to learn how to use a framework, the first being LESS and/or SCSS, you'll see that push and pull work within 12 columns and not on full width items. These classes only change the relative position left or right, respectively.
.col-sm-push-8 {
left: 66.66666667%;
}
.col-sm-pull-4 {
right: 33.33333333%;
}
When you open up the LESS mixins for the grid, you'll see that they didn't remove col-12-X from the push and pull or the offsets, but they are not used.
Bootstrap is not CSS, it's a framework that uses CSS. It doesn't provide a solution for every layout scenario or a class for every situation. GetBootstrap.com itself, all of the showcase sites, and nearly every theme or Bootstrap supported site on the planet uses custom CSS. You actually have to learn CSS to get the most out of a framework.
Another way, supported on current and legacy browsers is to use display:table on the parent and display:table-caption on the child you want to change the order of. See answer here by dfsq
https://stackoverflow.com/a/27432782/1004312
Make sure your images have width:100% on them (see the css example) if you intend to use responsive images with display:table as max-width:100% doesn't work on images inside tables.
The current, modern way using CSS alone is to use flexbox to put elements in the order that you want at a given breakpoint using media queries. Flexbox is supported on modern browsers.
http://caniuse.com/#feat=flexbox -- see the current support
Another way is to use jQuery insertBefore or insertAfter (whatever is required) on resize/load.
All of of these above methods are client side.
Another way, and it's my preferred way when the content is complicated, is to use server side code (such as php-mobile-detect) and serve up totally different html when the need arises, especially if the content is inappropriate (like freaking large images) for a small device.
Table Caption Example
HTML:
<h2>Table Caption</h2>
<div class="table-wrap">
<section class="content-Y">
<h2>A</h2>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
</section>
<section class="content-X">
<h2>B</h2>
<form action="#" method="post" role="form">
<div class="form-group">
<label for="name">Text Input:</label>
<input type="text" name="name" class="form-control" id="name" value="" tabindex="1" />
</div>
<div class="form-group">
<input type="submit" class="btn btn-default" value="Submit" />
</div>
</form>
</section>
</div>
CSS
/* table caption */
/* https://stackoverflow.com/questions/27432398/vertical-order-grid-in-bootstrap */
.content-X,
.content-Y {
border: 1px solid red;
margin: 0 0 10px 0;
}
@media (min-width: 768px) {
.table-wrap {
display: table;
}
.table-wrap img {width:100%;height:auto;}
.content-X {
display: table-caption;
}
}
Flexbox Example
HTML
<h2>Flexbox</h2>
<div class="flex-wrap">
<section class="content-2">
<h2>A</h2>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
</section>
<section class="content-1">
<h2>B</h2>
<form action="#" method="post" role="form">
<div class="form-group">
<label for="name">Text Input:</label>
<input type="text" name="name" class="form-control" id="name" value="" tabindex="1" />
</div>
<div class="form-group">
<input type="submit" class="btn btn-default" value="Submit" />
</div>
</form>
</section>
</div>
CSS
.content-1,
.content-2 {
border: 1px solid red;
margin: 0 0 10px 0;
}
@media (min-width:768px) {
.flex-wrap {
display: -moz-box;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-moz-box-orient: vertical;
-webkit-box-orient: vertical;
-webkit-flex-flow: column;
-ms-flex-direction: column;
flex-flow: column;
}
.content-1 {
-moz-box-ordinal-group: 1;
-webkit-box-ordinal-group: 1;
-webkit-order: 1;
-ms-flex-order: 1;
order: 1;
}
.content-2 {
-moz-box-ordinal-group: 2;
-webkit-box-ordinal-group: 2;
-webkit-order: 2;
-ms-flex-order: 2;
order: 2;
}
}
jQuery Example
HTML
<h2>jQuery InsertBefore</h2>
<div class="content-A">
<h2>A</h2>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
</div>
<div class="content-B">
<h2>B</h2>
<form action="#" method="post" role="form">
<div class="form-group">
<label for="name">Text Input:</label>
<input type="text" name="name2" class="form-control" id="name" value="" tabindex="1" />
</div>
<div class="form-group">
<input type="submit" class="btn btn-default" value="Submit" />
</div>
</form>
</div>
CSS
.content-A,
.content-B {
border: 1px solid red;
margin-bottom: 10px;
}
jQuery:
$(window).on("resize", function() {
if($(window).width() >= 768) {
$(".content-B").insertBefore($(".content-A"));
} else {
$(".content-A").insertBefore($(".content-B"));
}
}).resize();
*Note: .col-xs-12 is not required when using the grid system. Anything under the last min-width will be 100% width.
Full width items do not require the grid system, save yourself some extra wrappers.*