4

I have divs sorted 1, 2, 3 ... as html layout

HTML:

<div class="bigdiv">
    <div class="div1">div 1</div>
    <div class="div2">div 2</div>
    <div class="div3">div 3</div>
</div>

CSS:

.div1 {
    float: left; 
}

.div2 {
    float: left;     
 }

 .div3 {
    float: left;     
 }

How can I reorder divs to this layout with CSS

<div class="bigdiv">
    <div class="div3">div 3</div>
    <br>
    <div class="div1">div 1</div>
    <div class="div2">div 2</div>
</div>

by CSS (float, :after, :before)

My try:

.div3 {
    float: right; 
} 
.div3:before {
    content: '\A\A';
    white-space: pre;
}

Thank you in advance.

1
  • CSS is not the tool for this job; use javascript/jquery if you need to manipulate the DOM. Commented Aug 1, 2013 at 7:20

4 Answers 4

11

You can do this with the CSS Flexible Box Layout Module

The ‘order’ property controls the order in which flex items appear within their flex container, by assigning them to ordinal groups.

A flex container will lay out its content starting from the lowest numbered ordinal group and going up. Items with the same ordinal group are laid out in the order they appear in the source document. This also affects the painting order [CSS21], exactly as if the elements were reordered in the document. (W3.org)

FIDDLE

CSS (Without browser specifics)

.bigdiv {

    display: flex;
    flex-direction: row;
    }

.div1 {
    order: 2;
 }

.div2 {
    order: 3;
 }

.div3 {
    order: 1;
 }
Sign up to request clarification or add additional context in comments.

3 Comments

is there a way to have a linebreak after div3?
intresting solution (it is not working in jsfidle for me) ... I will try to test it, display: table; is working for me, +1 for efford
Wonderful and elegant solution. The flex property is a fine addition to CSS that I cannot stop using. It is simple yet powerful. This should be the accepted answer. Worked perfectly for me on the first try.
5

You could try to play around the display property and use this style:

CSS

.bigdiv { display:table; }

.div1, .div2 { float: left; }

.div3 {  display: table-header-group; }

Live example: http://jsbin.com/axekof/2/edit

Note the display:table; applied to the main wrapper and the display property applied to the .div3. The example should work even on IE8 (didn't tested)

As a sidenote, for .div3 you may use both display: table-caption and display: table-header-group, but there's a slight difference: with the first property, the parent element wraps only .div1 and .div2 while, with the latter, the container wraps all the children elements (try to apply a border to the .bigdiv so you can clearly see the difference)

Comments

2

HTML:

<div class="bigdiv">
    <div class="div1">div 1</div>
    <div class="div2">div 2</div>
    <div class="div3">div 3</div>
</div>

CSS:

.bigdiv {
    display:table;
    width:100%; 
}

.div1 {
    display: table-row-group;
}

.div2 {
    display: table-footer-group;
 }

 .div3 {
    display: table-header-group;
 }

The result will be:

div 3

div 1

div 2

And for those pesky early versions of Internet Explorer... Source

Old browsers IE6 and IE7 do not support CSS properties of display: table family.

Also, IE8 has a dynamic rendering bug that appears in some cases: if a block to move contains preudo-table elements (display: table*) (this is the only buggy case noticed currently), some pseudo-table cells (such cells as well as cells count are different each time the page is reloaded) may disappear randomly when the page is initially rendered.

So, for IE8 and lower, we can override CSS rules that make blocks tably, and additionally move blocks to required positions in DOM tree of HTML document with JavaScript instead of CSS:

/**
 * Reorders sibling elements in DOM tree according to specified order.
 * @param {Array} elems Sibling elements in desired block order.
 */
function reorderElements(elems) {
    var count = elems.length;

    if (!count) {
        return;
    }

    var parent = elems[0].parentNode;

    for (var i = count - 1; i >= 0; i--) {
        parent.insertBefore(elems[i], parent.firstChild);
    }
}

// If IE8 or lower
if (document.all && !document.addEventListener) {
    var blocks = [
        document.getElementById('div3'),
        document.getElementById('div2'),
        document.getElementById('div1')
    ];

    reorderElements(blocks);
}

Comments

-1

You can't do that with just CSS as I see you are manipulating the DOM. However if you would still want to achieve that you would need to use position:relative for bigdiv and position:absolute for .div1 .div2 and .div3, which are actually the children of .bigdiv. You would then need to use left, top, right, and bottom properties to style them as needed.

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.