25

How would I go about reordering divs without altering the HTML source code?

example, I want divs to appear in order #div2, #div1, #div3, but in the HTML they are:

<div id="#div1"></div>  
<div id="#div2"></div>  
<div id="#div3"></div>

Thanks!

1
  • Thank you for your answers. My current solution does what a lot of you recommended, it messes around with the HTML. I was wondering if there was a reliable way to do the sorting without touching the HTML, and I guess you guys have answered: no. I appreciate your help! Commented Feb 17, 2009 at 22:00

7 Answers 7

24

There is no catch-all way of reordering elements with css.

You can inverse their order horizontally by floating them all to the right. Or you can position them absolutely relative to the body or some other containing element - but that comes with severe limitations regarding the size of the elements, and positioning relative to other elements on the page.

Short answer: You can only achieve this in a very limited set of circumstances. Reordering elements is best done in markup.

If you have no control over the html, you could use javascript. Here using jQuery:

$("#div2").insertAfter("#div3");
$("#div1").prependTo("#div2");

I certainly don't recommend that unless your hands are tied. It will be harder to maintain, and for your end users it will make your page "jerk around" while its setting up the page.

Sign up to request clarification or add additional context in comments.

4 Comments

Your wording is unfortunate, because you're starting with a false statement. There is a catch-all way of reordering elements with CSS: order. It basically does not matter in what order they are in DOM, they will be displayed in the order specified by the element's order CSS prop, when this prop is specified (and valid).
Note: order only works inside elements with a display value of flex or grid (or their inline-* variants).
@tao While this is true visually, it's worth nothing that the CSS order property doesn't affect things like tab order between form fields.
@Sandwich, quite true. Tab order navigates elements in the order of tabindex. Elements with the same tabindex value are navigated in the order they are found in DOM tree. CSS order allows re-ordering sibling elements in a different order than they are found in DOM tree.
17

Since now flexbox is widely supported you can also use it to reorder divs using only css:

<div id="container">
    <div id="div1">1</div>  
    <div id="div2">2</div>  
    <div id="div3">3</div>
</div>

And css:

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

#div2{
  order:2
}

#div3{
  order:1
}

It would display:

1
3
2

You can try it on this fiddle.

2 Comments

Interesting! Using Javascript to change the CSS order attribute does not redraw the elements (e.g., element.style.order = 20;). Great. So it is possible to reorder elements without redraw!
Unfortunately MDN says you shouldn't to this if changing up the order is more than just a visual distraction ie. it actually has some meaning like in search results for example, because it isn't picked up on by screen readers: Since order is only meant to affect the visual order of elements and not their logical or tab order. order must not be used on non-visual media such as speech. developer.mozilla.org/en-US/docs/Web/CSS/order
14

I would use Javascript to traverse the nodes accordingly. If you want to use a library like jQuery, you can use the above suggestions. If you'd prefer not to have the bloat, use the following simple and minimalistic solution...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Test</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script type="text/javascript">
      function swapSibling(node1, node2) {
        node1.parentNode.replaceChild(node1, node2);
        node1.parentNode.insertBefore(node2, node1); 
      }

      window.onload = function() {
        swapSibling(document.getElementById('div1'), document.getElementById('div2'));
      }
    </script>
  </head>
  <body>
    <div id="div1">1</div>
    <div id="div2">2</div>
    <div id="div3">3</div>
  </body>
</html>

Best regards...

EDIT: Changed function name from swapNode to swapSibling, as I am fairly certain this will only work with nodes that have the same parent.

1 Comment

@ node1.parentNode.insertBefore(node2, node1); > will node1.parentNode still being referenced since node1 is replaced by node2 ?
11

In jQuery, you can do the following:

$("#div1").insertAfter("#div2");

That will move the element with id 'div1' to after element with id 'div2'. This assumes that you eliminate the '#' from your id attributes.

Comments

5

You could do, in Javascript:

function reOrder() {
  divOne = document.getElementById('#div1');
  divTwo = document.getElementById('#div2');
  divThree = document.getElementById('#div3');
  container = divOne.parentNode;
  container.appendChild(divTwo);
  container.appendChild(divOne);
  container.appendChild(divThree);
}

Edit: Fixed typo in IDs.

Comments

0

Since you tagged jQuery, you could use javascript to remove the elements and then re-insert them although that may not be all too flexible.

Having a bit more context would net you better answers I think.

Comments

0

It'll reorder while clicking on button

function reorderDiv() {
  let parent = document.getElementById('divContain');
  let children = parent.querySelectorAll('div');
  var arr = [];
  for (let i = 0; i < children.length; i++) {
    arr.push(children[i].innerHTML);
  }
  arr.unshift(children[children.length - 1].innerHTML);
  arr.splice(-1);
  for (let i = 0; i < arr.length; i++) {
    document.getElementById('div' + (i + 1)).innerHTML = arr[i];
  }

}
<!DOCTYPE html>
<html>
<head></head>
<body>
  <div id="divContain">
    <div id="div1">1</div>
    <div id="div2">2</div>
    <div id="div3">3</div>
  </div>
  <button onclick="reorderDiv()">Reordered</button>
</body>
</html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.