Swap DIV position with CSS only

I'm trying to swap two divs' locations for responsive design (the site looks different depending on width of the browser/good for mobile).

Right now I have something like this:

<div id="first_div"></div>
<div id="second_div"></div>

But would it be possible to swap their placements to make it look like second_div is first, using CSS only? The HTML stays the same. I've tried using floats and stuff but it doesn't seem to work the way I want it to. I don't want to use absolute positioning because the heights of the divs are always changing. Are there any solutions, or is there just no way to do this?


Someone linked me this: What is the best way to move an element that's on the top to the bottom in Responsive design.

The solution in that worked perfectly. Though it doesn’t support old IE, that doesn’t matter for me, since I’m using responsive design for mobile. And it works for most mobile browsers.

Basically, I had this:

@media (max-width: 30em) {
  .container {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    -webkit-box-orient: vertical;
    -moz-box-orient: vertical;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;
    /* optional */
    -webkit-box-align: start;
    -moz-box-align: start;
    -ms-flex-align: start;
    -webkit-align-items: flex-start;
    align-items: flex-start;
  }

  .container .first_div {
    -webkit-box-ordinal-group: 2;
    -moz-box-ordinal-group: 2;
    -ms-flex-order: 2;
    -webkit-order: 2;
    order: 2;
  }

  .container .second_div {
    -webkit-box-ordinal-group: 1;
    -moz-box-ordinal-group: 1;
    -ms-flex-order: 1;
    -webkit-order: 1;
    order: 1;
  }
}

This worked better than floats for me, because I needed them stacked on top of each other and I had about five different divs that I had to swap around the position of.


The accepted answer worked for most browsers but for some reason on iOS Chrome and Safari browsers the content that should have shown second was being hidden. I tried some other steps that forced content to stack on top of each other, and eventually I tried the following solution that gave me the intended effect (switch content display order on mobile screens), without bugs of stacked or hidden content:

.container {
  display:flex;
  flex-direction: column-reverse;
}

.section1,
.section2 {
  height: auto;
}

This question already has a great answer but in the spirit of exploring all possibilities here is another technique to reorder dom elements whilst still allowing them to take up their space, unlike the absolute positioning method.

This method works in all modern browsers and IE9+ (basically any browser that supports display:table) it has a drawback that it can only be used on a max of 3 siblings though.

//the html    
<div class='container'>
    <div class='div1'>1</div>
    <div class='div2'>2</div>
    <div class='div3'>3</div>
</div>

//the css
.container {
   display:table;    
}
.div1 {
    display:table-footer-group;
}
.div2 {
    display:table-header-group;
}
.div3 {
    display:table-row-group;
}

This will reorder the elements from 1,2,3 to 2,3,1. Basically anything with the display set to table-header-group will be positioned at the top and table-footer-group at the bottom. Naturally table-row-group puts an element in the middle.

This method is quick with good support and requires much less css than the flexbox approach so if you are only looking to swap a few items around for a mobile layout for example then dont rule out this technique.

You can check out a live demo on codepen: http://codepen.io/thepixelninja/pen/eZVgLx


In some cases you can just use the flex-box property order.

Very simple:

.flex-item {
    order: 2;
}

See: https://css-tricks.com/almanac/properties/o/order/


This solution worked for me:

Using a parent element like:

.parent-div {
    display:flex;
    flex-direction: column-reverse;
}

In my case I didn't have to change the css of the elements that I needed to switch.