Reputation: 272116
I have HTML markup that consists of three divs:
<div class="gallery">Gallery</div>
<div class="content">Content</div>
<div class="sidebar">Sidebar</div>
I want to present it in two different layouts using CSS (would be nicer if I could control whether the sidebar appears on left or right):
+------------------+
| Gallery |
+------+-----------+
| Side | Content |
| | |
+------+-----------+
+------+-----------+
| Side | Gallery |
+ +-----------+
| | Content |
| | |
+------+-----------+
In fact, it would be nicer if I could control whether the sidebar appears on left or right.
I can add additional divs and/or change the source order of divs as long as content appears before sidebar. But the HTML cannot be changed on per-layout basis.
Here is my incomplete attempt to solve the problem using flexbox + order property.
/* for demonstration */
.gallery { height: 100px; background-color: #CCC; }
.content { height: 200px; background-color: #EEE; }
.sidebar { height: 150px; background-color: #AAA; }
/* common */
.middle { display: flex; flex-direction: row; flex-wrap: wrap; }
/* layout-1 */
.middle.layout-1 .gallery { order: 1; width: 100%; }
.middle.layout-1 .content { order: 3; width: 75%; }
.middle.layout-1 .sidebar { order: 2; width: 25%; }
/* layout-2 */
.middle.layout-2 .gallery { order: 2; width: 75%; }
.middle.layout-2 .content { order: 3; width: 75%; }
.middle.layout-2 .sidebar { order: 1; width: 25%; }
<div class="middle layout-1">
<div class="gallery">Gallery</div>
<div class="content">Content (this layout works perfectly)</div>
<div class="sidebar">Sidebar</div>
</div>
<hr>
<div class="middle layout-2">
<div class="gallery">Gallery</div>
<div class="content">Content (should go below gallery)</div>
<div class="sidebar">Sidebar</div>
</div>
Upvotes: 9
Views: 3586
Reputation: 8246
Normally I avoid floats like the plague, but for this case they do what you need.
If you want to switch the side the sidebar is on, just swap the lefts and rights.
This will keep your layout with dynamic sized content:
.gallery {
background: red;
}
.content {
background: green;
}
.sidebar {
background: blue;
}
/* layout1 */
.layout1 .gallery {
width: 100%;
}
.layout1 .content {
width: 75%;
float: right;
}
.layout1 .sidebar {
width: 25%;
float: left;
}
/* layout2 */
.layout2 .gallery {
width: 75%;
float: right;
}
.layout2 .content {
width: 75%;
float: right;
}
.layout2 .sidebar {
width: 25%;
}
<div class="layout1">
<div class="gallery">Gallery</div>
<div class="content">Content</div>
<div class="sidebar">Sidebar</div>
</div>
<br>
<br>
<br>
<div class="layout2">
<div class="gallery">Gallery</div>
<div class="content">Content</div>
<div class="sidebar">Sidebar</div>
</div>
Upvotes: 3
Reputation: 128
Check this demo if you have containing div like .middle.layout-2
.
HTML:
<div class="middle layout-1">
<div class="gallery">Gallery</div>
<div class="content">Content (this layout works perfectly)</div>
<div class="sidebar">Sidebar</div>
</div>
<hr>
<div class="middle layout-2">
<div class="gallery">Gallery</div>
<div class="content">Content (should go below gallery)</div>
<div class="sidebar">Sidebar</div>
</div>
CSS:
/* for demonstration */
.gallery { height: 100px; background-color: #CCC; }
.content { height: 200px; background-color: #EEE; }
.sidebar { height: 200px; background-color: #AAA; }
/* common */
.middle { display: flex; flex-direction: row; flex-wrap: wrap; }
/* layout-1 */
.middle.layout-1 .gallery { order: 1; width: 100%; }
.middle.layout-1 .content { order: 3; width: 75%; }
.middle.layout-1 .sidebar { order: 2; width: 25%; }
/* layout-2 */
.middle.layout-2 { position: relative; }
.middle.layout-2 .gallery { width: 75%; margin-left: 25%; }
.middle.layout-2 .content { width: 75%; margin-left: 25%; }
.middle.layout-2 .sidebar { position: absolute; top: 0; left: 0; width: 25%; height: 100%;}
Upvotes: 5
Reputation: 18099
Let me know if this is what you want:
HTML:
First Layout
<div class="container one">
<div class="gallery">Gallery</div>
<div class="sidebar">Sidebar</div>
<div class="content">Content</div>
</div>
<br/>Second Layout
<div class="container two">
<div class="gallery">Gallery</div>
<div class="sidebar">Sidebar</div>
<div class="content">Content</div>
</div>
<br/>Third Layout
<div class="container three">
<div class="gallery">Gallery</div>
<div class="sidebar">Sidebar</div>
<div class="content">Content</div>
</div>
<br/>
CSS:
html, body {
width:100%:height:100%:
}
* {
box-sizing:border-box;
white-space:nowrap;
}
.container {
width:500px;
height:500px;
position:relative;
}
.container div {
border:1px solid black;
padding:20px;
}
/*One*/
.one.container .sidebar, .one.container .content {
float:left;
width:50%;
}
.one.container:after {
clear:both;
display:block;
content:"";
}
/*Two*/
.two.container .sidebar {
float:right;
width:50%;
}
.two.container .content {
float:left;
width:50%;
}
.two.container:after {
clear:both;
display:block;
content:"";
}
/*Three*/
.three.container>div {
position:absolute;
}
.three.container .gallery {
top:0;
left:50%;
right:0;
height:50%;
}
.three.container .sidebar {
top:0;
left:0;
bottom:0;
width:50%;
}
.three.container .content {
top:50%;
left:50%;
right:0;
height:50%;
bottom:0;
}
Demo: http://jsfiddle.net/GCu2D/665/
This doesn't have additional div or markup. You need to just toggle the classe in the container
.
Upvotes: 1