How can I reorder my divs using only CSS?
Given a template where the HTML cannot be modified because of other requirements, how is it possible to display (rearrange) a div
above another div
when they are not in that order in the HTML? Both div
s contain data that varies in height and width.
<div id="wrapper">
<div id="firstDiv">
Content to be below in this situation
</div>
<div id="secondDiv">
Content to be above in this situation
</div>
</div>
Other elements
Hopefully it is obvious that the desired result is:
Content to be above in this situation
Content to be below in this situation
Other elements
When the dimensions are fixed it easy to position them where needed, but I need some ideas for when the content is variable. For the sake of this scenario, please just consider the width to be 100% on both.
I am specifically looking for a CSS-only solution (and it will probably have to be met with other solutions if that doesn't pan out).
There are other elements following this. A good suggestion was mentioned given the limited scenario I demonstrated—given that it might be the best answer, but I am looking to also make sure elements following this aren't impacted.
Solution 1:
This solution uses only CSS and works with variable content
#wrapper { display: table; }
#firstDiv { display: table-footer-group; }
#secondDiv { display: table-header-group; }
Solution 2:
A CSS-only solution (works for IE10+) – use Flexbox's order
property:
Demo: http://jsfiddle.net/hqya7q6o/596/
#flex { display: flex; flex-direction: column; }
#a { order: 2; }
#b { order: 1; }
#c { order: 3; }
<div id="flex">
<div id="a">A</div>
<div id="b">B</div>
<div id="c">C</div>
</div>
More info: https://developer.mozilla.org/en-US/docs/Web/CSS/order
Solution 3:
As others have said, this isn't something you'd want to be doing in CSS. You can fudge it with absolute positioning and strange margins, but it's just not a robust solution. The best option in your case would be to turn to javascript. In jQuery, this is a very simple task:
$('#secondDiv').insertBefore('#firstDiv');
or more generically:
$('.swapMe').each(function(i, el) {
$(el).insertBefore($(el).prev());
});
Solution 4:
This can be done using Flexbox.
Create a container that applies both display:flex and flex-flow:column-reverse.
/* -- Where the Magic Happens -- */
.container {
/* Setup Flexbox */
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
/* Reverse Column Order */
-webkit-flex-flow: column-reverse;
flex-flow: column-reverse;
}
/* -- Styling Only -- */
.container > div {
background: red;
color: white;
padding: 10px;
}
.container > div:last-of-type {
background: blue;
}
<div class="container">
<div class="first">
first
</div>
<div class="second">
second
</div>
</div>
Sources:
- https://css-tricks.com/using-flexbox/
- https://developer.mozilla.org/en-US/docs/Web/CSS/flex-flow#Browser_compatibility