Is there a way to define a content flow in CSS using flex or other techniques such that content "zig zags" or goes around in this way:
-----------------
|A > B > C > D > E|
|J < I < H < G < F|
-----------------
---
|A H|
|B G|
|C F|
|D E|
---
Assume there are always 2 columns or rows. I could split the items in 2 and create 2 wrapping items around them, but I would like it to be more dynamic.
Basically, how do I make the first row flow to the right and the second flow to the left?
If you only want scrollbars to appear when there is more content than can fit in the box, use overflow: auto . This allows the browser to determine if it should display scrollbars. In the example below, remove content until it fits into the box. You should see the scrollbars disappear.
Add overflow: hidden; to hide both the horizontal and vertical scrollbar.
I was able to do this with Flexbox and a bit of JavaScript (I was unable to do it with CSS alone):
var reverseBoxes = function () {
var flexItems = document.querySelectorAll(".child"),
flexItemsCount = flexItems.length,
reverseAt = flexItems.length / 2,
breakPoint = 480;
for (var i = reverseAt; i < flexItemsCount; i++) {
flexItems[i].style.order = flexItemsCount - i;
}
for (var j = 0; j < flexItemsCount; j++) {
if (window.innerWidth > breakPoint) {
flexItems[j].style.width = (100 / flexItemsCount) * 2 - 2 + "%";
flexItems[j].style.height = "auto";
} else {
flexItems[j].style.height = (100 / flexItemsCount) * 2 - 2 + "%";
flexItems[j].style.width = "auto";
}
}
}
reverseBoxes();
window.addEventListener("resize", reverseBoxes);
body {
font-family: Arial, sans-serif;
font-size: 18px;
margin: 0;
padding: 0;
}
.parent {
display: flex;
flex-wrap: wrap;
list-style-type: none;
padding: 0;
height: 100vh;
}
.child {
margin: 1%;
text-align: center;
background: #069;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
@media only screen and (max-width: 480px) {
.parent {
flex-direction: column;
}
.child {
width: 48%;
}
}
<div class="parent">
<div class="child">A</div>
<div class="child">B</div>
<div class="child">C</div>
<div class="child">D</div>
<div class="child">E</div>
<div class="child">F</div>
<div class="child">G</div>
<div class="child">H</div>
<div class="child">I</div>
<div class="child">J</div>
</div>
Is it what you ware looking for?
The following solution does not use JavaScript and somewhat scalable. I use display: flex
so that I could use the order
property.
The basic idea is to assign order: 1
to the last item, order: 2
to the second last item and so on. The first half of the items have order: -1
and a pseudo element having order: 0
is used as a separator. The tricky part is where you figure out the "first half" of items:
.demo {
display: flex;
flex-direction: row;
flex-wrap: wrap;
background: #EEE;
}
.demo > * {
margin: .5em;
width: 4em;
height: 4em;
background: #0CF;
}
/*
* the example work for a list of 20 elements
* for additional elements extend the repeating selectors
*/
/* all items ordered backwards */
.demo > :nth-last-child(1) { order: 1; }
.demo > :nth-last-child(2) { order: 2; }
.demo > :nth-last-child(3) { order: 3; }
.demo > :nth-last-child(4) { order: 4; }
.demo > :nth-last-child(5) { order: 5; }
.demo > :nth-last-child(6) { order: 6; }
.demo > :nth-last-child(7) { order: 7; }
.demo > :nth-last-child(8) { order: 8; }
.demo > :nth-last-child(9) { order: 9; }
.demo > :nth-last-child(10) { order: 10; }
/* first half items are source ordered */
.demo> :nth-child(-n+0):nth-last-child(n+1),
.demo> :nth-child(-n+1):nth-last-child(n+2),
.demo> :nth-child(-n+2):nth-last-child(n+3),
.demo> :nth-child(-n+3):nth-last-child(n+4),
.demo> :nth-child(-n+4):nth-last-child(n+5),
.demo> :nth-child(-n+5):nth-last-child(n+6),
.demo> :nth-child(-n+6):nth-last-child(n+7),
.demo> :nth-child(-n+7):nth-last-child(n+8),
.demo> :nth-child(-n+8):nth-last-child(n+9),
.demo> :nth-child(-n+9):nth-last-child(n+10),
.demo> :nth-child(-n+10):nth-last-child(n+11) {
order: -1;
}
/* the separator uses flex-basis trick and ordered between the two halves */
.demo::after {
content: "";
flex-basis: 100%;
order: 0;
}
<div class="demo">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
For two column layout, specify flex-direction: column; height: 25em
on the parent (height must be fixed).
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