Switching the order of block elements with CSS [duplicate]
Short Story
Let's say my HTML is already set in stone:
<div id="blockA">Block A</div>
<div id="blockB">Block B</div>
<div id="blockC">Block C</div>
It will look like this:
------------
| Block A |
------------
| Block B |
------------
| Block C |
------------
Now I want to switch the order of the blocks. How can I do that with only CSS?
------------
| Block C |
------------
| Block A |
------------
| Block B |
------------
I'm aware there's hacky solutions such as using position:absolute
, but this doesn't preserve the effective use of the display:block
property. That is, blocks push other blocks downward when they grow in size.
Long Story
When user uses a computer to view my webpage, the blocks are displayed in this order:
- General info.
- Event schedule.
- iPhone app advertisement
The iPhone app advertisement is placed last because it's not terribly important to computer users. A small percentage of computer users will whip out their phone and install the app.
If a mobile user comes to this site, the iPhone app advertisement should be the most important thing on the page. Therefore, it should be moved to the top:
- iPhone app advertisement
- General info.
- Event schedule.
I would like iPhone and computer users to share the same HTML, but have a CSS media query switch the order of the blocks.
@media only screen and (max-device-width: 480px) {
#blockC {
/* magic order switching */
}
}
Solution 1:
Here is a "simple as possible" example, for changing the order of div-elements (when resizing the browser window):
<!DOCTYPE html>
<html>
<head>
<title>foobar</title>
<style>
@media screen and (max-width:300px){
#parent{
display:flex;
flex-flow: column;
}
#a{order:2;}
#c{order:1;}
#b{order:3;}
}
</style>
</head>
<body>
<div id="parent">
<div id="a">one</div>
<div id="b">two</div>
<div id="c">three</div>
</div>
</body>
</html>
Example: http://jsfiddle.net/devnull/qyroxexv/ (change window-width to see the effect of changing the order of the divs)
Solution 2:
As has already been suggested, Flexbox is the answer - particularly because you only need to support a single modern browser: Mobile Safari.
See: http://jsfiddle.net/thirtydot/hLUHL/
You can remove the -moz-
prefixed properties if you like, I just left them in for future readers.
#blockContainer {
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: vertical;
-moz-box-orient: vertical;
box-orient: vertical;
}
#blockA {
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
box-ordinal-group: 2;
}
#blockB {
-webkit-box-ordinal-group: 3;
-moz-box-ordinal-group: 3;
box-ordinal-group: 3;
}
<div id="blockContainer">
<div id="blockA">Block A</div>
<div id="blockB">Block B</div>
<div id="blockC">Block C</div>
</div>
Solution 3:
Update: Two lightweight CSS solutions:
Using flex, flex-flow and order:
Example1: Demo Fiddle
body{
display:flex;
flex-flow: column;
}
#blockA{
order:4;
}
#blockB{
order:3;
}
#blockC{
order:2;
}
Alternatively, reverse the Y scale:
Example2: Demo Fiddle
body{
-webkit-transform: scaleY(-1);
transform: scaleY(-1);
}
div{
-webkit-transform: scaleY(-1);
transform: scaleY(-1);
}