Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change div order with CSS depending on device-width

Tags:

html

css

flexbox

I am working on a responsive site and came across an interesting problem. I have some divs side by side. There could be anywhere from 2 to 6 or so of them. When the screen isn't wide enough to show all the content properly, the divs stack vertically. Simple enough to do with CSS.

The problem is, I need them to be in a different order depending on the layout. This is easy to do with 2 or 3 divs (Changing divs order based on width), but significantly more challenging when you add a fourth.

I could use position: absolute; and manually set the position, however this causes the parent to shrink and not contain them properly.

To make this even more complicated, I can't use JavaScript.

Working with two columns:

(untested)

HTML:

<div id="container">     <div class="column-half column-half-2">         First div on mobile, right div on desktop     </div>     <div class="column-half column-half-1">         Second div on mobile, left div on desktop     </div> </div> 

CSS:

.container {     width: 80%;     max-width: 1200px;     margin: 0 auto;     padding-bottom: 20px;     position: relative; } .column-half {     display: table-cell;     padding: 25px;     vertical-align: top;     width: 40%; } .column-half-1 {     float: left; } .column-half-2 {     float: right; } 

HTML, with 4 columns:

<div id="container">     <div class="column-quarter column-quarter-3">         First div on mobile, third div on desktop     </div>     <div class="column-quarter column-quarter-2">         Second div on mobile, second div on desktop     </div>     <div class="column-quarter column-quarter-1">         Third div on mobile, first div on desktop     </div>     <div class="column-quarter column-quarter-4">         Fourth div on mobile, fourth div on desktop     </div> </div> 
like image 409
3ocene Avatar asked Sep 28 '15 18:09

3ocene


People also ask

How can I reorder my divs using only CSS?

We can reorder HTML elements by using many methods in CSS. We use flexbox's order property. Order property is used to change the visual order and not their logical order. Items in a container are sorted in ascending order value and then by their source code order.

How do I make div width auto adjust?

Using width, max-width and margin: auto; Then, you can set the margins to auto, to horizontally center the element within its container. The element will take up the specified width, and the remaining space will be split equally between the two margins: This <div> element has a width of 500px, and margin set to auto.

How do I keep two side by side div elements the same width?

The two or more different div of same height can be put side-by-side using CSS. Use CSS property to set the height and width of div and use display property to place div in side-by-side format.


1 Answers

This is doable in CSS thanks to the wonderful flexbox spec. Using the order and flex-flow properties, we can achieve what you want. Unprefixed, IE11 and all evergreen browsers will support this. IE10 prefixes -ms-order and doesn't support flex-flow.

The solution takes into consideration all the constraints you listed:

  • Have a list of elements in a given order displayed as a row.
  • When the window is too small, change them to display in a column.
  • Change the order of the elements when they are displayed in a column.

Because of the limitations of Stack Snippets, you'll need to view the demo in Full page mode, and resize your browser to see the effect.

.container div {      width: 100px;      height: 50px;      display: inline-block;  }    .one { background: red; }  .two { background: orange; }  .three { background: yellow; }  .four { background: green; }  .five { background: blue; }    @media screen and (max-width: 531px) {      .container { display: flex; flex-flow: column; }      .five { order: 1; }      .four { order: 2;  }      .three { order: 3; }      .two { order: 4; }      .one { order: 5 }  }
<div class="container">      <div class="one">I'm first</div>      <div class="two">I'm second</div>      <div class="three">I'm third</div>      <div class="four">I'm fourth</div>      <div class="five">I'm fifth</div>  </div>

Alternatively, here is a JSFiddle demo.


You can also simply use flex-flow: column-reverse without the order property assigned to each div, if you are so inclined against verbose CSS. The same demo restrictions apply; view this demo in full screen and resize the browser window accordingly.

.container div {      width: 100px;      height: 50px;      display: inline-block;  }    .one { background: red; }  .two { background: orange; }  .three { background: yellow; }  .four { background: green; }  .five { background: blue; }    @media screen and (max-width: 531px) {      .container { display: flex; flex-flow: column-reverse; }  }
<div class="container">      <div class="one">I'm first</div>      <div class="two">I'm second</div>      <div class="three">I'm third</div>      <div class="four">I'm fourth</div>      <div class="five">I'm fifth</div>  </div>

It's worth pointing out that flex-flow is a shorthand property encompassing both flex-direction and flex-wrap properties.

like image 189
TylerH Avatar answered Oct 08 '22 02:10

TylerH