Michael Eugene Yuen Michael Eugene Yuen - 2 months ago 13
CSS Question

How to change order of divs on smaller screens?

I need to reorder the divs when screen size is less than 480px.

I don't want to use

position: absolute
because the height of the green area may vary due to amount of text.

I need the small screen order to be red, green, red, green, red, green (each red being on top of the immediate green and width being 100%).

Any idea? Many thanks



*, html, body {
margin: 0;
padding: 0;
}

.container {
width: 100%;
display: inline-block;
box-sizing: border-box;
}

.full_half {
display: inline-block;
width: 50%;
background-color: green;
float: left;
min-height: 100px;
}

.pic {
background-color: red;
height: 100px;
}

.text {
box-sizing: border-box;
padding: 20px 120px;
}

@media screen and (max-width: 480px) {
.full_half {
width: 100%;
}

.text{
padding: 0 0 !important;
}
}

<div class="container">
<div class="full_half pic"></div>
<div class="full_half text">test</div>
</div>
<div class="container">
<div class="full_half text">test</div>
<div class="full_half pic"></div>
</div>
<div class="container">
<div class="full_half pic"></div>
<div class="full_half text">
dfdfdfdfdfdffdfdfdfdfdfdfdfdfdfdf<br />
dfdfdfdfdfdffdfdfdfdfdfdfdfdfdfdf<br />
dfdfdfdfdfdffdfdfdfdfdfdfdfdfdfdf<br />
</div>
</div>





SOLVED:

I have finally managed to changed the order by applying flexbox to the container (only when width is less than 480px).

css change:

@media screen and (max-width: 480px) {
.container {
flex-direction: column;
}
.pic {
order: 1;
}

.text{
order: 2;
}
}


http://jsfiddle.net/vquf7z7b/

Answer

With CSS Flexbox you can control the visual order of elements with the order property and the main axis of the divs with the flex-direction property.

Here are a few simple adjustments to your code that achieve your goal:

CSS

.container {
     display: flex; /* NEW */

    /* width: 100%; */
    /* display: inline-block; */
    /* box-sizing: border-box; */
}

   @media screen and (max-width: 480px) {
    .full_half {
      width: 100%;
    }

    .text{
     padding: 0 0 !important;
    }

    .container { flex-direction: column; }  /* NEW */

    .container:nth-child(2) > .pic { order: -1; }  /* NEW */
}

Now when the screen size is less than 480px the divs are stacked in a single column and the order is red, green, red, green, red, green.

DEMO

In the example above, child elements of the flex container (.container) are aligned in a row, which is the default layout of a flexbox (flex-direction: row).

Each child element is by default assigned a value of 0 in the row order. By giving the div with the .pic class in the second .container a value of -1, it gets positioned before its sibling (div with .text with a value of 0). We could also have given the first sibling a value of 1, thus moving it after div with .pic. Learn more about the order property.

By changing the value of flex-direction from its default (row) to column, the divs stack up in a single column. Learn more about the flex-direction property.


Browser support

Flexbox is supported by all major browsers, except IE < 10.

Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes.

For a quick way to add all the prefixes you need, use Autoprefixer.

More details in this answer.