I have three boxes that I'd like to put in various combinations into a container. A box will sometimes be present in a combination, sometimes not.
If all three boxes are in the container, there should be a full-width box on top, and two half-width boxese in a row underneath.
If two boxes are in the container, there should only be two half-width boxes.
If there is one box, it should be full-width.
I came up with a solution which uses wrap: wrap-reverse, but it requires you to put elements in reverse order in your html. Minor annoyance.
So I used flex-direction: row-reverse and order to reverse the order of the content.
I have a small problem with this solution because using order makes for a less flexible solution if we want to let the same css handle 5 boxes, for instance.
Right now I'm leaning toward not using order and just living with the reversed html. What do you think? Am I missing a silver bullet somewhere?
https://jsfiddle.net/uesje5dq/
.container {
display: flex;
flex-wrap: wrap-reverse;
flex-direction: row-reverse;
}
.item {
flex: 1;
flex-basis: 50%;
}
.item:nth-child(1) {
order: 3;
}
.item:nth-child(2) {
order: 2;
}
.item:nth-child(3) {
order: 1;
}
===========================================================================
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div class="container">
<div class="item" style="height: 100px;width:100%;background-color: red;"></div>
<div class="item" style="height: 100px;width:100%;background-color: green;"></div>
<div class="item" style="height: 100px;width:100%;background-color: blue;"></div>
</div>
</body>
</html>
If you combine the first-child
and nth-last-child
you can count the amount of children, like this, where if there is only 1 or 3, the first is full width, otherwise they are half wide.
And the .item:first-child:nth-last-child(3)
rule works like that, when the first child is also the 3rd from the end, we know there is 3 items, and the rule kicks in.
Stack snippet
.container {
display: flex;
flex-wrap: wrap;
}
.item:only-child,
.item:first-child:nth-last-child(3) {
flex-basis: 100%;
}
.item {
flex-basis: 50%;
}
<div class="container">
<div class="item" style="height: 100px;width:100%;background-color: red;"></div>
<div class="item" style="height: 100px;width:100%;background-color: green;"></div>
<div class="item" style="height: 100px;width:100%;background-color: blue;"></div>
</div>
<hr>
<div class="container">
<div class="item" style="height: 100px;width:100%;background-color: red;"></div>
<div class="item" style="height: 100px;width:100%;background-color: green;"></div>
</div>
<hr>
<div class="container">
<div class="item" style="height: 100px;width:100%;background-color: red;"></div>
</div>
With this logic you can also check if there is 5, and when, make the first full width and the rest half.
Stack snippet
.container {
display: flex;
flex-wrap: wrap;
}
.item:only-child,
.item:first-child:nth-last-child(3),
.item:first-child:nth-last-child(5) {
flex-basis: 100%;
}
.item {
flex-basis: 50%;
}
<div class="container">
<div class="item" style="height: 100px;width:100%;background-color: red;"></div>
<div class="item" style="height: 100px;width:100%;background-color: green;"></div>
<div class="item" style="height: 100px;width:100%;background-color: blue;"></div>
<div class="item" style="height: 100px;width:100%;background-color: yellow;"></div>
<div class="item" style="height: 100px;width:100%;background-color: purple;"></div>
</div>
Or on an unknown amount of items, and when an uneven amount, the first has full width and the rest half.
Stack snippet
.container {
display: flex;
flex-wrap: wrap;
}
.item:first-child:nth-last-child(odd) {
flex-basis: 100%;
}
.item {
flex-basis: 50%;
}
<div>9 items</div>
<div class="container">
<div class="item" style="height: 100px;width:100%;background-color: red;"></div>
<div class="item" style="height: 100px;width:100%;background-color: green;"></div>
<div class="item" style="height: 100px;width:100%;background-color: blue;"></div>
<div class="item" style="height: 100px;width:100%;background-color: yellow;"></div>
<div class="item" style="height: 100px;width:100%;background-color: purple;"></div>
<div class="item" style="height: 100px;width:100%;background-color: red;"></div>
<div class="item" style="height: 100px;width:100%;background-color: green;"></div>
<div class="item" style="height: 100px;width:100%;background-color: blue;"></div>
<div class="item" style="height: 100px;width:100%;background-color: yellow;"></div>
</div>
<div><br>7 items</div>
<div class="container">
<div class="item" style="height: 100px;width:100%;background-color: red;"></div>
<div class="item" style="height: 100px;width:100%;background-color: green;"></div>
<div class="item" style="height: 100px;width:100%;background-color: blue;"></div>
<div class="item" style="height: 100px;width:100%;background-color: yellow;"></div>
<div class="item" style="height: 100px;width:100%;background-color: purple;"></div>
<div class="item" style="height: 100px;width:100%;background-color: red;"></div>
<div class="item" style="height: 100px;width:100%;background-color: green;"></div>
</div>
<div><br>6 items</div>
<div class="container">
<div class="item" style="height: 100px;width:100%;background-color: red;"></div>
<div class="item" style="height: 100px;width:100%;background-color: green;"></div>
<div class="item" style="height: 100px;width:100%;background-color: blue;"></div>
<div class="item" style="height: 100px;width:100%;background-color: yellow;"></div>
<div class="item" style="height: 100px;width:100%;background-color: purple;"></div>
<div class="item" style="height: 100px;width:100%;background-color: red;"></div>
</div>
And here is few more interesting ways to count the amount of children:
FlexBox align (stretch) last Item
Can CSS detect the number of children an element has?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With