16

JSFIDDLE

I want to change the order of floated divs at a certain pixel size.

At default state they both have 50% width and they are next to each other.

Below 600px screen size (or w/e does not matter) I want the second div(red one) float above first div(yellow one).

How is this possible with CSS only solution?

HTML

<div class="yellow"></div>
<div class="red"></div>

CSS

.yellow {
    background: yellow;
    width: 50%;
    height: 300px;
    float:left;
}

.red {
    background: red;
    width: 50%;
    height: 300px;
    float:left;
}

@media screen and (max-width:600px) {
    .yellow {
        background: yellow;
        width: 100%;
        height: 300px;
        float:left;
    }

    .red {
        background: red;
        width: 100%;
        height: 300px;
        float:left;
    }
}

The solution I want is:

RED DIV

YELLOW DIV

but now it is:

YELLOW DIV

RED DIV

vaskort
  • 2,591
  • 2
  • 20
  • 29
  • 2
    [This](http://jsfiddle.net/uh7zLphk/1/) is a slightly different approach but has a change to the HTML. – Harry Sep 07 '14 at 12:37
  • Nice one but you will only get the "feel" that they float:left only if they both have 50% width. I will change the pixels of each one to a fixed value. – vaskort Sep 07 '14 at 12:40
  • 1
    True that. [This](http://jsfiddle.net/uh7zLphk/11/) is another possible approach. – Harry Sep 07 '14 at 12:44
  • What do you mean 'float above the first'? They should be display block, or that the red div should be first on the line? – David Thomas Sep 07 '14 at 12:49
  • I added explanation in my question – vaskort Sep 07 '14 at 12:57
  • So, to clarify: When the width of the page is *more than 600px* you want the elements to be side-by-side, at 50% width (with the yellow div first)? And at *less than 600px* you want the elements to be 100% width and the red div first in the page? – David Thomas Sep 07 '14 at 13:26
  • @DavidThomas Thats right! – vaskort Sep 07 '14 at 13:28
  • @Harry I think the second link you gave is the most clean approach. Will wait or I will tell you to make an answer and accept. – vaskort Sep 07 '14 at 14:16
  • @BillK: Not a problem mate. Just ping me via comments in case you don't get a better answer and I will add mine as one. – Harry Sep 07 '14 at 14:18
  • 1
    This is the mobile first way of doing it, it's fewer lines of css http://jsfiddle.net/mhrf6d4n/ – Christina Sep 07 '14 at 17:35
  • And here's one that makes it look all slidy: http://jsfiddle.net/mhrf6d4n/1/ – Christina Sep 07 '14 at 17:37
  • Possible duplicate of [Use CSS to reorder DIVs](http://stackoverflow.com/questions/220273/use-css-to-reorder-divs) – Damjan Pavlica Sep 30 '16 at 13:19

4 Answers4

24

I know that you're asking how to accomplish this utilising floats, but as far as I know using pure CSS this is impossible (at least without using nasty positioning, which you've said you don't want to do).

As far as I know the only nice way to accomplish this with pure HTML/CSS is to utilise the new flexbox spec (a good starting point would probably be this css tricks article).

When you use flexbox you can use the order property on items to dictate which order items appear in (duh)

You can see an example of this in action here, the HTML code is similar to what you have, with an added wrapper element (I also fixed the DOCTYPE declaration):

<!DOCTYPE html>
<div class="wrapper">
    <div class="yellow">
    </div>
    <div class="red">
    </div>
</div>

The CSS is a little different:

.wrapper {
  display: flex;
  flex-flow: row wrap;
}

.yellow {
    background: yellow;
    width: 20%;
    height: 300px;
}

.red {
    background: red;
    width: 20%;
    height: 300px;
}

@media screen and (max-width:600px) {
    .yellow {
        order: 2;
        width: 100%;
    }

    .red {
        order: 1;
        width: 100%;
    }
}

I've also cleaned it up a little, you had duplicate code in your media query which didn't really need to be there.

The only downside to this is that it currently only works on around 80% of browsers as of writing:

http://caniuse.com/#search=flexbox

Depending on your target market that might be OK, you could use graceful degradation so that it appears correctly in all ways except the ordering on devices that don't support flexbox fully.

I guess you're also only really targeting mobile devices with reordering things, support there is good so it might work well for you.

Sean
  • 6,389
  • 9
  • 45
  • 69
7

Try to change your

HTML to this -

<div class="container">
  <div class="yellow"></div>
  <div class="red"></div>
</div>

and your @media query CSS to this -

@media screen and (max-width:600px) {
.container{
    display:flex;
    flex-direction: column-reverse;
}
.yellow {
    background: yellow;
    width: 100%;
    height: 300px;

}

.red {
    background: red;
    width: 100%;
    height: 300px;


} }
Ramiz Wachtler
  • 5,623
  • 2
  • 28
  • 33
6

Here is a simple solution using negative margins and floats.

For the CSS, use the following:

@media screen and (max-width:600px) {
    .yellow {
        background: yellow;
        width: 100%;
        height: 300px;
        float:left;
        margin-top: 300px;
    }

    .red {
        background: red;
        width: 100%;
        height: 300px;
        float:left;
        margin-left: -100%;
    }
}

Your HTML remains the same as you posted.

Add a top margin to .yellow using margin-top: 300px (equal to the height of the red div).

For the red div, add a negative left margin of 100%.

This will force the red div to position itself over the yellow div, but since you have the yellow div a top margin, the yellow div pops out under the red div.

The trick is similar to that used for the Holy Grail 3-column layout design.

See demo: http://jsfiddle.net/audetwebdesign/jux84wzk/

Marc Audet
  • 46,011
  • 11
  • 63
  • 83
2

So far, there are no mobile first answers, which is fewer lines of css, and other benefits. This does touch the html, so it's not the OP's question, for a CSS only approach it's the Flexbox answer from two other peeps, which I have voted up.

DEMO: http://jsfiddle.net/mhrf6d4n/

HTML, put in source order of the smallest viewport first:

<div class="red"></div>
<div class="yellow"></div>

CSS (put the shared, global to all viewports outside of media queries, combine shared selectors, then after put the min-width and put your floats in there)

.yellow, .red {
    background: yellow;
    height: 300px;
}
.red {
    background: red;
}

@media screen and (min-width:600px) {
    .yellow, .red {
        float:left;
        width:50%;
    }
}
Christina
  • 34,296
  • 17
  • 83
  • 119
  • The problem with mobile first CSS is that whilst being 'nicer' and 'more efficient' it messes up the styles for IE8- (IE8 ignores any css inside a media query) – Sean Sep 07 '14 at 20:20
  • 1
    respond.js, been using it since 2011. There's a point when you really don't want to have to load up small viewport users with large viewport styles and background images that are huge. – Christina Sep 07 '14 at 20:23
  • Interesting, I've not heard of that before (although it seems a polyfill exists for anything, so it does make sense). Looks like I'm coding my next site mobile first :) thanks! – Sean Sep 07 '14 at 22:44