How can I reorder my divs using only CSS?

HtmlCss

Html Problem Overview


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 divs 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.

Html Solutions


Solution 1 - Html

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 2 - Html

This solution uses only CSS and works with variable content

#wrapper   { display: table; }
#firstDiv  { display: table-footer-group; }
#secondDiv { display: table-header-group; }

Solution 3 - Html

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 - Html

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:

Solution 5 - Html

There is absolutely no way to achieve what you want through CSS alone while supporting pre-flexbox user agents (mostly old IE) -- unless:

  1. You know the exact rendered height of each element (if so, you can absolutely position the content). If you're dealing with dynamically generated content, you're out of luck.
  2. You know the exact number of these elements there will be. Again, if you need to do this for several chunks of content that are generated dynamically, you're out of luck, especially if there are more than three or so.

If the above are true then you can do what you want by absolutely positioning the elements --

#wrapper { position: relative; }
#firstDiv { position: absolute; height: 100px; top: 110px; }
#secondDiv { position: absolute; height: 100px; top: 0; }

Again, if you don't know the height want for at least #firstDiv, there's no way you can do what you want via CSS alone. If any of this content is dynamic, you will have to use javascript.

Solution 6 - Html

Here's a solution:

<style>
#firstDiv {
	position:absolute; top:100%;
}
#wrapper {
	position:relative; 
}

But I suspect you have some content that follows the wrapper div...

Solution 7 - Html

With CSS3 flexbox layout module, you can order divs.

#wrapper {
  display: flex;
  flex-direction: column;
}
#firstDiv {
  order: 2;
}

<div id="wrapper">
  <div id="firstDiv">
    Content1
  </div>
  <div id="secondDiv">
    Content2
  </div>
</div>

Solution 8 - Html

You can use Flex

#wrapper {
  display: flex;
  flex-direction: column;
}

#firstDiv {
  order: 1;
}

#secondDiv {
  order: 0;
}

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

Solution 9 - Html

If you know, or can enforce the size for the to-be-upper element, you could use

position : absolute;

In your css and give the divs their position.

otherwise javascript seems the only way to go:

fd = document.getElementById( 'firstDiv' );
sd = document.getElementById( 'secondDiv' );
fd.parentNode.removeChild( fd );
sd.parentNode.insertAfter( fd, sd );

or something similar.

edit: I just found this which might be useful: w3 document css3 move-to

Solution 10 - Html

Negative top margins can achieve this effect, but they would need to be customized for each page. For instance, this markup...

<div class="product">
<h2>Greatest Product Ever</h2>
<p class="desc">This paragraph appears in the source code directly after the heading and will appear in the search results.</p>
<p class="sidenote">Note: This information appears in HTML after the product description appearing below.</p>
</div>

...and this CSS...

.product { width: 400px; }
.desc { margin-top: 5em; }
.sidenote { margin-top: -7em; }

...would allow you to pull the second paragraph above the first.

Of course, you'll have to manually tweak your CSS for different description lengths so that the intro paragraph jumps up the appropriate amount, but if you have limited control over the other parts and full control over markup and CSS then this might be an option.

Solution 11 - Html

If you just use css, you can use flex.

.price {
    display: flex;
    align-items: center;
    justify-content: center;

    flex-direction: row-reverse; //revert horizontally
    //flex-direction: column-reverse; revert vertically
}

<div class="price">
      <div>first block</div>
      <div>second block</div>
</div>

Solution 12 - Html

Ordering only for mobile and keep the native order for desktop:

// html

<div>
  <div class="gridInverseMobile1">First</div>
  <div class="gridInverseMobile1">Second</div>
</div>

// css

@media only screen and (max-width: 960px) {
  .gridInverseMobile1 {
    order: 2;
    -webkit-order: 2;
  }
  .gridInverseMobile2 {
    order: 1;
    -webkit-order: 1;
  }
}

Result:

Desktop: First | Second
Mobile: Second | First

source: https://www.w3schools.com/cssref/css3_pr_order.asp

Solution 13 - Html

Well, with a bit of absolute positioning and some dodgy margin setting, I can get close, but it's not perfect or pretty:

#wrapper { position: relative; margin-top: 4em; }
#firstDiv { position: absolute; top: 0; width: 100%; }
#secondDiv { position: absolute; bottom: 0; width: 100%; }

The "margin-top: 4em" is the particularly nasty bit: this margin needs to be adjusted according to the amount of content in the firstDiv. Depending on your exact requirements, this might be possible, but I'm hoping anyway that someone might be able to build on this for a solid solution.

Eric's comment about JavaScript should probably be pursued.

Solution 14 - Html

In your CSS, float the first div by left or right. Float the second div by left or right same as first. Apply clear: left or right the same as the above two divs for the second div.

For example:

#firstDiv {
	float: left;
}

#secondDiv {
	float: left;
	clear: left;
}

Solution 15 - Html

This can be done with CSS only!

Please check my answer to this similar question:

https://stackoverflow.com/a/25462829/1077230

I don't want to double post my answer but the short of it is that the parent needs to become a flexbox element. Eg:

(only using the webkit vendor prefix here.)

#main {
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-flex-direction: column;
    flex-direction: column;
    -webkit-box-align: start;
    -webkit-align-items: flex-start;
    align-items: flex-start;
}

Then, swap divs around by indicating their order with:

#main > div#one{
    -webkit-box-ordinal-group: 2;
    -moz-box-ordinal-group: 2;
    -ms-flex-order: 2;
    -webkit-order: 2;
    order: 2;
    overflow:visible;
}

#main > div#two{
    -webkit-box-ordinal-group: 1;
    -moz-box-ordinal-group: 1;
    -ms-flex-order: 1;
    -webkit-order: 1;
    order: 1;
}

Solution 16 - Html

I was looking for a way to change the orders of the divs only for mobile version so then I can style it nicely. Thanks to nickf reply I got to make this piece of code which worked well for what I wanted, so i though of sharing it with you guys:

//  changing the order of the sidebar so it goes after the content for mobile versions
jQuery(window).resize(function(){
    if ( jQuery(window).width() < 480 )
    {
        jQuery('#main-content').insertBefore('#sidebar');
    }
    if ( jQuery(window).width() > 480 )
    {
        jQuery('#sidebar').insertBefore('#main-content');
    }
    jQuery(window).height(); // New height
    jQuery(window).width(); // New width
});

Solution 17 - Html

A solution with a bigger browser support then the flexbox (works in IE≥9):

#wrapper {
  -webkit-transform: scaleY(-1);
  -ms-transform: scaleY(-1);
  transform: scaleY(-1);
}
#wrapper > * {
  -webkit-transform: scaleY(-1);
  -ms-transform: scaleY(-1);
  transform: scaleY(-1);
}

<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

In contrast to the display: table; solution this solution works when .wrapper has any amount of children.

Solution 18 - Html

Just use flex for the parent div by specifying display: flex and flex-direction : column. Then use order to determine which of the child div comes first

Solution 19 - Html

If you want to reverse displaying order of children. I suggest you use this

> direction: rtl; // Right to left

Set this property in parent element

Solution 20 - Html

CSS really shouldn't be used to restructure the HTML backend. However, it is possible if you know the height of both elements involved and are feeling hackish. Also, text selection will be messed up when going between the divs, but that's because the HTML and CSS order are opposite.

#firstDiv { position: relative; top: YYYpx; height: XXXpx; }
#secondDiv { position: relative; top: -XXXpx; height: YYYpx; }

Where XXX and YYY are the heights of firstDiv and secondDiv respectively. This will work with trailing elements, unlike the top answer.

Solution 21 - Html

I have a much better code, made by me, it is so big, just to show both things... create a 4x4 table and vertical align more than just one cell.

It does not use any IE hack, no vertical-align:middle; at all...

It does not use for vertical centering display-table, display:table-rom; display:table-cell;

It uses the trick of a container that has two divs, one hidden (position is not the correct but makes parent have the correct variable size), one visible just after the hidden but with top:-50%; so it is mover to correct position.

See div classes that make the trick: BloqueTipoContenedor BloqueTipoContenedor_VerticalmenteCentrado BloqueTipoContenido_VerticalmenteCentrado_Oculto BloqueTipoContenido_VerticalmenteCentrado_Visible

Please sorry for using Spanish on classes names (it is because i speak spanish and this is so tricky that if i use English i get lost).

The full code:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Language" content="en" />
<meta name="language" content="en" />
<title>Vertical Centering in CSS2 - Example (IE, FF & Chrome tested) - This is so tricky!!!</title>
<style type="text/css">
 html,body{
  margin:0px;
  padding:0px;
  width:100%;
  height:100%;
 }
 div.BloqueTipoTabla{
  display:table;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoFila_AltoAjustadoAlContenido{
  display:table-row;margin:0px;border:0px;padding:0px;width:100%;height:auto;
 }
 div.BloqueTipoFila_AltoRestante{
  display:table-row;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoCelda_AjustadoAlContenido{
  display:table-cell;margin:0px;border:0px;padding:0px;width:auto;height:auto;
 }
 div.BloqueTipoCelda_RestanteAncho{
  display:table-cell;margin:0px;border:0px;padding:0px;width:100%;height:auto;
 }
 div.BloqueTipoCelda_RestanteAlto{
  display:table-cell;margin:0px;border:0px;padding:0px;width:auto;height:100%;
 }
 div.BloqueTipoCelda_RestanteAnchoAlto{
  display:table-cell;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoContenedor{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:100%;position:relative;
 }
 div.BloqueTipoContenedor_VerticalmenteCentrado{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;position:relative;top:50%;
 }
 div.BloqueTipoContenido_VerticalmenteCentrado_Oculto{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;visibility:hidden;position:relative;top:50%;
 }
 div.BloqueTipoContenido_VerticalmenteCentrado_Visible{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;visibility:visible;position:absolute;top:-50%;
 }
</style>
</head>
<body>
<h1>Vertical Centering in CSS2 - Example<br />(IE, FF & Chrome tested)<br />This is so tricky!!!</h1>
<div class="BloqueTipoTabla" style="margin:0px 0px 0px 25px;width:75%;height:66%;border:1px solid blue;">
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [1,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,4]
  </div>
 </div>
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [2,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,4]
  </div>
</div>
 <div class="BloqueTipoFila_AltoRestante">
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
     The cell [3,1]
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     Now&nbsp;is&nbsp;the&nbsp;highest&nbsp;one
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
     The cell [3,1]
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     Now&nbsp;is&nbsp;the&nbsp;highest&nbsp;one
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This&nbsp;is<br />cell&nbsp;[3,2]
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This&nbsp;is<br />cell&nbsp;[3,2]
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAnchoAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This is cell [3,3]
      <br/>
      It is duplicated on source to make the trick to know its variable height
      <br />
      First copy is hidden and second copy is visible
      <br/>
      Other cells of this row are not correctly aligned only on IE!!!
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This is cell [3,3]
      <br/>
      It is duplicated on source to make the trick to know its variable height
      <br />
      First copy is hidden and second copy is visible
      <br/>
      Other cells of this row are not correctly aligned only on IE!!!
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This&nbsp;other is<br />the cell&nbsp;[3,4]
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This&nbsp;other is<br />the cell&nbsp;[3,4]
     </div>
    </div>
   </div>
  </div>
 </div>
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [4,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,4]
  </div>
 </div>
</div>
</body>
</html>

Solution 22 - Html

Little late to the party, but you can also do this:

<div style="height: 500px; width: 500px;">

<div class="bottom" style="height: 250px; width: 500px; background: red; margin-top: 250px;"></div>

<div class="top" style="height: 250px; width: 500px; background: blue; margin-top: -500px;"></div>

Solution 23 - Html

Or set an absolute position to the element and work off the margins by declaring them from the edge of the page rather than the edge of the object. Use % as its more suitable for other screen sizes ect. This is how i overcame the issue...Thanks, hope its what your looking for...

Solution 24 - Html

For CSS Only solution

  1. Either height of wrapper should be fixed or
  2. height of second div should be fixed

Solution 25 - Html

.move-wrap {
	display: table;
	table-layout: fixed; // prevent some responsive bugs
	width: 100%; // set a width if u like
	/* TODO: js-fallback IE7 if u like ms */
}

.move-down {
	display: table-footer-group;
}

.move-up {
	display: table-header-group;
}

Solution 26 - Html

It is easy with css, just use display:block and z-index property

Here is an example:

HTML:

<body>
	<div class="wrapper">

		<div class="header">
			header
		</div>

		<div class="content">
			content
		</div>
	</div>
</body>

CSS:

.wrapper
{
	[...]
}

.header
{
	[...]
	z-index:9001;
	display:block;
	[...]
}

.content
{
	[...]
	z-index:9000;
	[...]
}

Edit: It is good to set some background-color to the div-s to see things properly.

Solution 27 - Html

I have a simple way to do this.

<!--  HTML  -->

<div class="wrapper">

    <div class="sm-hide">This content hides when at your layouts chosen breaking point.</div>

    <div>Content that stays in place</div>
    
    <div class="sm-show">This content is set to show at your layouts chosen breaking point.</div>

</div>

<!--  CSS  -->

    .sm-hide {display:block;}
    .sm-show {display:none;}

@media (max-width:598px) {
    .sm-hide {display:none;}
    .sm-show {display:block;}
}

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
QuestiondevmodeView Question on Stackoverflow
Solution 1 - HtmlJustinView Answer on Stackoverflow
Solution 2 - HtmlJordiView Answer on Stackoverflow
Solution 3 - HtmlnickfView Answer on Stackoverflow
Solution 4 - HtmlBlakePetersenView Answer on Stackoverflow
Solution 5 - HtmlMatt HowellView Answer on Stackoverflow
Solution 6 - Htmlbuti-oxaView Answer on Stackoverflow
Solution 7 - HtmlArun Kumar MView Answer on Stackoverflow
Solution 8 - HtmlAleandro CoppolaView Answer on Stackoverflow
Solution 9 - HtmlKrisView Answer on Stackoverflow
Solution 10 - HtmlCarl CameraView Answer on Stackoverflow
Solution 11 - Htmlal-bulatView Answer on Stackoverflow
Solution 12 - HtmlAlanView Answer on Stackoverflow
Solution 13 - HtmlBobby JackView Answer on Stackoverflow
Solution 14 - HtmlReza AmyaView Answer on Stackoverflow
Solution 15 - Htmljansmolders86View Answer on Stackoverflow
Solution 16 - HtmlJose PaitamalaView Answer on Stackoverflow
Solution 17 - HtmlFinesseView Answer on Stackoverflow
Solution 18 - HtmlMUSTAPHA ABDULRASHEEDView Answer on Stackoverflow
Solution 19 - HtmlChuong TranView Answer on Stackoverflow
Solution 20 - Htmluser65952View Answer on Stackoverflow
Solution 21 - Htmlz666zz666zView Answer on Stackoverflow
Solution 22 - HtmllsromView Answer on Stackoverflow
Solution 23 - HtmlTom DenleyView Answer on Stackoverflow
Solution 24 - HtmlKoolKabinView Answer on Stackoverflow
Solution 25 - HtmlK.KutscheraView Answer on Stackoverflow
Solution 26 - HtmlPmillanView Answer on Stackoverflow
Solution 27 - HtmlGian MillerView Answer on Stackoverflow