Reshuffling the display order of DIVs based on css media query?

jeffkee picture jeffkee · Mar 17, 2012 · Viewed 7.2k times · Source

Check out this page: http://new.brixwork.com/realtors/real-estate-website-features

Below the big computer screen, the images and text blocks alternate in a staircase design.. on one div the image is on the right, on another, on the left. And there are 4 blocks.

I'm using the Skeleton framework (www.getskeleton.com) for a responsive grid design, so the grid re-sizes on the viewport queries, which is great. however this poses a problem on iphones or vertical view on iPads when the image & text boxes shuffle to get on top of each other.

Instead of

image text text image image text text image

I get

image text text image image text text image

Because of the order by which the objects were typed out in my HTML.

So the question is, is there a clever way to re-position items via CSS? I already use media queries like this:

    @media only screen and (max-width: 959px) {

}

/* Tablet Portrait size to standard 960 (devices and browsers) */
@media only screen and (min-width: 768px) and (max-width: 959px) {

}

/* All Mobile Sizes (devices and browser) */
@media only screen and (max-width: 767px) {

}

/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */
@media only screen and (min-width: 480px) and (max-width: 767px) {

}

/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */
@media only screen and (max-width: 479px) {

}

Any ideas? I want to do this without resorting to jQuery to detect the window size and re-size them if I can avoid it. I can't use PHP to alter the DIV orders on "echo", because I want the re-shuffling to be done effectively if a tablet is taken from horizontal to a vertical position.

Answer

Greg Pettit picture Greg Pettit · Mar 17, 2012

Where there's a will, there's a way! The big drawback with using a framework that uses semantics like "six columns alpha" and "ten columns omega" is that they create an expectation for visual ordering. The six columns are on the left, the ten columns are on the right, and the alpha/omega naming conventions affect margins because the order is right in the markup. You have stumbled across an unexpected use case for the author, I'm thinking.

(Incidentally, your ten column area also contains images that are overflowing their containers; ie. they're not being resized)

The straight goods:

My honest advice for future maintainability is to learn from skeleton, take what you want from it understanding what its different classes do... and re-invent it.

For example, what you have on your main page are a series of feature containers. The markup should look consistent, like this:

<div class="featurebox">
  <div class="media">Image, slider, or other visual interest items here</div>
  <div class="items">Text of items of interest</div>
</div>
<div class="featurebox">
  <div class="media">A different image, slider, etc</div>
  <div class="items">More text of items of interest</div>
</div>

And then you can style these to create the left-right effect. The key here is in the selectors. By floating right instead of left for divs inside every other featurebox, our effect is easily achieved:

.featurebox { width: 600px; overflow: hidden; clear: both;}

.featurebox div { float: left; }
.featurebox:nth-of-type(odd) div { float: right; }

.items { width: 200px }
.media {background-color: grey; width:400px; height: 100px;}

Fiddle: http://jsfiddle.net/7qRfh/

The problem in modifying what you currently have is that this doesn't really fit skeleton's expectation of left-to-right stacking of floats. If you're willing to say "phooey" you could identify your containers, target every second one, and flip the .columns float orientation. You will also need to override omega and alpha class behaviour so that omega is actually acting like alpha and vice versa. A mess, in my opinion, but it'll work.

The hack

I just had a fiddle around here and I think I closed it. Can't find the URL in my history so I may not have saved it first. :-/

But no matter. It boiled down to this: you can do what you need to do with your current markup, but the changes to CSS are even more extensive and become nutty.

The container already has position: absolute, so you have to unfloat the "six" and "ten" columns, position them absolutely, with "ten" on top and "six" on the bottom. The big issue is that do to it easily, the container as well as the "six" and "ten" all need to have height set on them. Absolute positioning takes an element out of document flow, so without height it just becomes an overlapping weird mess.

Honestly, if you insist on skeleton the way it is, and the markup the way it is, the most reasonable hack actually turns out to be JavaScript. If you already have jQuery on your page, all the easier.