Swap DIV position with CSS only

CssResponsive Design

Css Problem Overview


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?

Css Solutions


Solution 1 - Css

Someone linked me this: <https://stackoverflow.com/questions/17115995/what-is-the-best-way-to-move-an-element-thats-on-the-top-to-the-bottom-in-respo>;.

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.

Solution 2 - Css

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;
}

Solution 3 - Css

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

Solution 4 - Css

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.

Solution 5 - Css

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/

Solution 6 - Css

enter image description here

Using CSS only:

#blockContainer {
  display: -webkit-box;
  display: -moz-box;
  display: box;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  box-orient: vertical;
}

#blockA {
  -webkit-box-ordinal-group: 2;
  -moz-box-ordinal-group: 2;
  box-ordinal-group: 2;
}

#blockB {
  -webkit-box-ordinal-group: 3;
  -moz-box-ordinal-group: 3;
  box-ordinal-group: 3;
}

<div id="blockContainer">
  <div id="blockA">Block A</div>
  <div id="blockB">Block B</div>
  <div id="blockC">Block C</div>
</div>

Solution 7 - Css

Assuming Nothing Follows Them

If these two div elements are basically your main layout elements, and nothing follows them in the html, then there is a pure HMTL/CSS solution that takes the normal order shown in this fiddle and is able to flip it vertically as shown in this fiddle using one additional wrapper div like so:

HTML

<div class="wrapper flipit">
   <div id="first_div">first div</div>
   <div id="second_div">second div</div>
</div>

CSS

.flipit {
    position: relative;
}
.flipit #first_div {
    position: absolute;
    top: 100%;
    width: 100%;
}

This would not work if elements follow these div's, as this fiddle illustrates the issue if the following elements are not wrapped (they get overlapped by #first_div), and this fiddle illustrates the issue if the following elements are also wrapped (the #first_div changes position with both the #second_div and the following elements). So that is why, depending on your use case, this method may or may not work.

For an overall layout scheme, where all other elements exist inside the two div's, it can work. For other scenarios, it will not.

Solution 8 - Css

assuming both elements have 50% width, here is what i used:

css:

  .parent {
    width: 100%;
    display: flex;
  }  
  .child-1 {
	width: 50%;
    margin-right: -50%;
    margin-left: 50%;
    background: #ff0;
  }
  .child-2 {
	width: 50%;
    margin-right: 50%;
    margin-left: -50%;
    background: #0f0;
  }

html:

<div class="parent">
  <div class="child-1">child1</div>
  <div class="child-2">child2</div>
</div>

example: https://jsfiddle.net/gzveri/o6umhj53/

btw, this approach works for any 2 nearby elements in a long list of elements. For example I have a long list of elements with 2 items per row and I want each 3-rd and 4-th element in the list to be swapped, so that it renders elements in a chess style, then I use these rules:

  .parent > div:nth-child(4n+3) {
    margin-right: -50%;
    margin-left: 50%;
  }
  .parent > div:nth-child(4n+4) {
    margin-right: 50%;
    margin-left: -50%;
  }

Solution 9 - Css

Yesterday ran into the same problem. Grid areas worked out great in my case:

.content-body {
    display: grid;
    grid-template-areas: " left right ";
    grid-template-columns: 1fr 1fr;
}
.first_div {
    grid-area: right;
}
.second {
    grid-area: left;
}

Solution 10 - Css

You don't need anything fancy. Make a copy of your second div, and place it on top. Like this

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

Give the second_div_copy display: none when you want first div to appear on top. Give the second_div_copy display: block, and the second_div display: none when you want the second div to appear on top.

It's really that simple. Or am I missing something ?

Solution 11 - Css

Simple flexbox solution utilizing the order-property:

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

.first {
  order: 3;
}

.second {
  order: 2;
}

<div class="container">
  <div class="first">First</div>
  <div class="second">Second</div>
  <div class="third">Third</div>
</div>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDragonflyView Question on Stackoverflow
Solution 1 - CssDragonflyView Answer on Stackoverflow
Solution 2 - CssJason AwbreyView Answer on Stackoverflow
Solution 3 - CssEd FryedView Answer on Stackoverflow
Solution 4 - CsspfmDevView Answer on Stackoverflow
Solution 5 - CssBoris YakubchikView Answer on Stackoverflow
Solution 6 - CssiqmakerView Answer on Stackoverflow
Solution 7 - CssScottSView Answer on Stackoverflow
Solution 8 - CssGZveriView Answer on Stackoverflow
Solution 9 - CssMax TuzenkoView Answer on Stackoverflow
Solution 10 - CssRobView Answer on Stackoverflow
Solution 11 - CssleonheessView Answer on Stackoverflow