Reputation: 11468
I would like to make three column layout with CSS. Is it possible that the column items flow in arbitrary order and I only "assign" them to a given column or do they have to be structured so that they first fill the first column, then the second and third? The items have the same width, but different height. Also, the columns may each have vastly different number of items. For example:
(1) For a structure:
container:
#1 div .red
#2 div .green
#3 div .green
#4 div .blue
#5 div .red
#6 div .green
#7 div .blue
is it possible to style it with CSS so that it falls into three columns like:
.red .green .blue
+--------+ +--------+ +--------+
|#1 | |#2 | |#4 |
| | +--------+ | |
+--------+ +--------+ | |
+--------+ |#3 | | |
|#5 | | | +--------+
| | +--------+ +--------+
| | +--------+ |#7 |
| | |#6 | +--------+
+--------+ | |
| |
+--------+
(2) or does it have to be structured like:
container:
#1 div .red
#2 div .red
#3 div .green
#4 div .green
#5 div .green
#6 div .blue
#7 div .blue
for:
.red .green .blue
+--------+ +--------+ +--------+
|#1 | |#3 | |#6 |
| | +--------+ | |
+--------+ +--------+ | |
+--------+ |#4 | | |
|#2 | | | +--------+
| | +--------+ +--------+
| | +--------+ |#7 |
| | |#5 | +--------+
+--------+ | |
| |
+--------+
(3) Or even:
container for .red:
#1 div .red
#2 div .red
container for .green:
#3 div .green
#4 div .green
#5 div .green
container for .blue:
#6 div .blue
#7 div .blue
for:
.red .green .blue
+------------+ +------------+ +------------+
| +--------+ | | +--------+ | | +--------+ |
| |#1 | | | |#3 | | | |#6 | |
| | | | | +--------+ | | | | |
| +--------+ | | +--------+ | | | | |
| +--------+ | | |#4 | | | | | |
| |#2 | | | | | | | +--------+ |
| | | | | +--------+ | | +--------+ |
| | | | | +--------+ | | |#7 | |
| | | | | |#5 | | | +--------+ |
| +--------+ | | | | | | |
| | | | | | | |
| | | +--------+ | | |
+------------+ +------------+ +------------+
How would CSS for the first (1) case look like, if possible?
Upvotes: 1
Views: 81
Reputation: 64164
If you can give the container a definite height, you can solve it with flex-box, setting an order for the classes, and adding pseudo-elements to act as "breakers" to force the wrap:
Those psuedo would be invisibles in production; I have made one of them visible just for demo purposes
.container {
width: 500px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
border: solid 1px red;
height: 500px;
}
.container div {
width: 28%;
margin: 10px;
}
.container div:nth-child(odd) {
height: 130px;
}
.container div:nth-child(even) {
height: 80px;
}
.container:before {
content: "";
width: 6px;
/* only for demo */
background-color: gray;
/* only for demo */
height: 100%;
order: 15;
}
.container:after {
content: "";
height: 100%;
order: 25;
}
.red {
order: 10;
background-color: red;
}
.green {
order: 20;
background-color: green;
}
.blue {
order: 30;
background-color: blue;
}
<div class="container">
<div class="red"></div>
<div class="green"></div>
<div class="green"></div>
<div class="blue"></div>
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
</div>
Upvotes: 1
Reputation: 8668
Ok here is a solution that maybe answers the question better.
You have 3 columns each with an unknown number of items, each you click shuffle the items will order randomly. If you want this to happen when the page loads just remove the $('#shuffle').click(function() {
and ending });
and delete the button
$('#shuffle').click(function() {
$('#box_container .box').each(function() {
var itemCount = $('.item', this).length;
$('.item', this).each(function() {
var order = Math.floor(Math.random() * itemCount) + 1;
$(this).css('order', order);
});
});
});
#box_container {
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-around;
}
.box {
color: #ddd;
text-align: center;
flex-basis: 30%;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
.item {
background: rgba(255, 255, 255, 0.25);
height: 50px;
width: 80%;
border: 1px solid black;
}
.red { background: red;}
.blue { background: blue;}
.green { background: green;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<button id="shuffle">Shuffle</button>
<div id="box_container">
<div class="box red">
<div class="item item1">1</div>
<div class="item item2">2</div>
<div class="item item3">3</div>
</div>
<div class="box blue">
<div class="item item1">1</div>
<div class="item item2">2</div>
<div class="item item3">3</div>
</div>
<div class="box green">
<div class="item item1">1</div>
<div class="item item2">2</div>
<div class="item item3">3</div>
</div>
</div>
Upvotes: 0
Reputation:
If you're interested in attaining your second example where the heights are variable and things just slot in to fill the specified columns then have a look at this
http://codepen.io/hoonin_hooligan/pen/OXbGBP
.your-column-wrapper {
overflow: hidden;
-webkit-column-count: 3;
-webkit-column-gap: 15px;
-webkit-column-fill: auto;
padding-left: 15px;
padding-right: 15px;
margin-top: 10px;
}
.your-column-content {
background-color: #fff;
margin-bottom: 15px;
-webkit-column-break-inside: avoid;
page-break-inside: avoid;
break-inside: avoid;
}
This is something I built a while back that could be a good place to start or use for your use case.
Upvotes: 0
Reputation: 8668
You could use flex box for this. Just add the order
property to the items:
e.g. box1 {order:5;}
will put box 1 in 5th position.
.container {
width: 100%;
display: flex;
flex-direction:row;
flex-wrap: wrap;
justify-content:space-around;
}
.box {
height: 200px;
color: #fff;
text-align: center;
flex-basis:30%;
margin-top:5px;
}
.box p {
padding-top: 90px;
}
.red {
background: red;
order:4;
}
.blue {
background: blue;
order:3;
}
.green {
background: green;
order:5;
}
.orange {
background: orange;
order:6;
}
.pink {
background: pink;
order:2;
}
.purple {
background: purple;
order:1;
}
<div class="container">
<div class="box red"><p>1</p></div>
<div class="box blue"><p>2</p></div>
<div class="box green"><p>3</p></div>
<div class="box orange"><p>4</p></div>
<div class="box pink"><p>5</p></div>
<div class="box purple"><p>6</p></div>
</div>
Upvotes: 0