I am trying to create a responsive layout with Flexbox which allows me to alternate both the directions row
and row-reverse
.
我正在尝试用Flexbox创建一个响应式布局,它允许我交替方向行和行反向。
Maybe you can understand it better with some image (mind the order of the boxes):
也许你可以通过一些图片(注意盒子的顺序)更好地理解它:
And resizing:
和调整:
Or still:
或者还是:
You can imagine an arrow that goes through each box, it must be possible to go through 1 to 8 following the sequence of numbers (like a snake).
你可以想象一个箭头穿过每一个盒子,它必须能够按照数字序列(像一条蛇)经过1到8。
How can I achieve it using flexbox?
我如何使用flexbox实现它?
I think I can use the order
CSS property, but I miss a dynamic way to set it. I don't think I can achieve this result with JavaScript since there's no a way to get the dynamic row's number (except with ugly hacks, and I want to avoid them). So, do you have any idea?
我想我可以使用order CSS属性,但是我错过了一个动态设置的方法。我不认为我可以用JavaScript实现这个结果,因为没有办法获得动态行号(除了一些难看的技巧,我想避免它们)。你知道吗?
Thank you.
谢谢你!
If you want to write an example based on my code, you can use this:
如果你想根据我的代码写一个例子,你可以这样:
.flexbox-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
width: 380px;
height: 100px;
background: red;
margin: 5px;
font-family: sans-serif;
color: white;
text-align: center;
font-size: 2em;
line-height: 150%;
}
<div class="flexbox-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
2 个解决方案
#1
2
Given the fact the items have a known width, this can be done using order
and media queries, not with row
/reverse-row
, unless each row has a wrapper, which won't be possible in your case.
考虑到项目具有已知的宽度,这可以使用order和media查询完成,而不是使用row/reverse row,除非每一行都有一个包装器,这在您的情况下是不可能的。
Stack snippet
堆栈段
body {margin: 0}
.flexbox-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
width: 380px;
height: 100px;
background: red;
margin: 5px;
font-family: sans-serif;
color: white;
text-align: center;
font-size: 2em;
line-height: 150%;
}
@media (min-width: 796px) {
.flex-item:nth-child(3) { order: 2; }
.flex-item:nth-child(4) { order: 1; }
.flex-item:nth-child(n+5) { order: 2; }
.flex-item:nth-child(7) { order: 4; }
.flex-item:nth-child(8) { order: 3; }
}
@media (min-width: 1176px) {
.flex-item:nth-child(3) { order: 0; }
.flex-item:nth-child(4) { order: 3; }
.flex-item:nth-child(5) { order: 2; }
.flex-item:nth-child(6) { order: 1; }
.flex-item:nth-child(n+7) { order: 3; }
.flex-item:nth-child(8) { order: 3; }
}
@media (min-width: 1556px) {
.flex-item:nth-child(3) { order: 0; }
.flex-item:nth-child(4) { order: 0; }
.flex-item:nth-child(5) { order: 4; }
.flex-item:nth-child(6) { order: 3; }
.flex-item:nth-child(7) { order: 2; }
.flex-item:nth-child(8) { order: 1; }
}
<div class="flexbox-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
If the size of the items are not known, here is a jQuery version.
如果不知道条目的大小,这是jQuery版本。
Note, assigning the order
value needs to be done in one go, or else it won't work, as if to start changing value for one item at a time, that change will be executed immediately and will affect the next items position.
注意,分配订单值需要一次性完成,否则它将不起作用,就像每次开始更改一个项目的值一样,该更改将立即执行,并将影响下一个项目的位置。
Codepen演示
Stack snippet
堆栈段
(function ($) {
// preload object array to gain performance
var $items = $('.flexbox-container .flex-item');
// run at resize
$( window ).resize(function() {
$.fn.setOrder(false,0);
});
$.fn.setOrder = function(reverse,idx) {
var $order = [];
$items.each(function(i, obj) {
// did top value changed
if (i != 0 && $items.eq(i - 1).offset().top != $(obj).offset().top) {
reverse = !reverse;
// insert index when reverse
idx = i;
}
if (reverse) {
$order.splice(idx, 0, i);
} else {
$order.push(i);
}
});
// set item's order
$items.css('order', function(i, val) {
return $order[i];
});
}
// run at load
$.fn.setOrder(false,0);
}(jQuery));
.flexbox-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
width: 200px;
height: 100px;
background: red;
margin: 5px;
font-family: sans-serif;
color: white;
text-align: center;
font-size: 2em;
line-height: 150%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flexbox-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
#2
3
The only way I can see this happening is by manually setting the order and then using media queries for your breakpoints - here is an example
我能看到这种情况发生的唯一方法是手动设置订单,然后对断点使用媒体查询——这里有一个例子
.flexbox-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
width: calc(50% - 10px);
height: 100px;
background: red;
margin: 5px;
font-family: sans-serif;
color: white;
text-align: center;
font-size: 2em;
line-height: 150%;
}
.flex-item:nth-child(1) {
order: 1;
}
.flex-item:nth-child(2) {
order: 2;
}
.flex-item:nth-child(3) {
order: 4;
}
.flex-item:nth-child(4) {
order: 3;
}
.flex-item:nth-child(5) {
order: 5;
}
.flex-item:nth-child(6) {
order: 6;
}
.flex-item:nth-child(7) {
order: 8;
}
.flex-item:nth-child(8) {
order: 7;
}
@media only screen and (max-width: 768px) {
.flex-item {
width: calc(33.33333% - 10px);
}
.flex-item:nth-child(1) {
order: 1;
}
.flex-item:nth-child(2) {
order: 2;
}
.flex-item:nth-child(3) {
order: 3;
}
.flex-item:nth-child(4) {
order: 6;
}
.flex-item:nth-child(5) {
order: 5;
}
.flex-item:nth-child(6) {
order: 4;
}
.flex-item:nth-child(7) {
order: 7;
}
.flex-item:nth-child(8) {
order: 8;
}
<div class="flexbox-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
#1
2
Given the fact the items have a known width, this can be done using order
and media queries, not with row
/reverse-row
, unless each row has a wrapper, which won't be possible in your case.
考虑到项目具有已知的宽度,这可以使用order和media查询完成,而不是使用row/reverse row,除非每一行都有一个包装器,这在您的情况下是不可能的。
Stack snippet
堆栈段
body {margin: 0}
.flexbox-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
width: 380px;
height: 100px;
background: red;
margin: 5px;
font-family: sans-serif;
color: white;
text-align: center;
font-size: 2em;
line-height: 150%;
}
@media (min-width: 796px) {
.flex-item:nth-child(3) { order: 2; }
.flex-item:nth-child(4) { order: 1; }
.flex-item:nth-child(n+5) { order: 2; }
.flex-item:nth-child(7) { order: 4; }
.flex-item:nth-child(8) { order: 3; }
}
@media (min-width: 1176px) {
.flex-item:nth-child(3) { order: 0; }
.flex-item:nth-child(4) { order: 3; }
.flex-item:nth-child(5) { order: 2; }
.flex-item:nth-child(6) { order: 1; }
.flex-item:nth-child(n+7) { order: 3; }
.flex-item:nth-child(8) { order: 3; }
}
@media (min-width: 1556px) {
.flex-item:nth-child(3) { order: 0; }
.flex-item:nth-child(4) { order: 0; }
.flex-item:nth-child(5) { order: 4; }
.flex-item:nth-child(6) { order: 3; }
.flex-item:nth-child(7) { order: 2; }
.flex-item:nth-child(8) { order: 1; }
}
<div class="flexbox-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
If the size of the items are not known, here is a jQuery version.
如果不知道条目的大小,这是jQuery版本。
Note, assigning the order
value needs to be done in one go, or else it won't work, as if to start changing value for one item at a time, that change will be executed immediately and will affect the next items position.
注意,分配订单值需要一次性完成,否则它将不起作用,就像每次开始更改一个项目的值一样,该更改将立即执行,并将影响下一个项目的位置。
Codepen演示
Stack snippet
堆栈段
(function ($) {
// preload object array to gain performance
var $items = $('.flexbox-container .flex-item');
// run at resize
$( window ).resize(function() {
$.fn.setOrder(false,0);
});
$.fn.setOrder = function(reverse,idx) {
var $order = [];
$items.each(function(i, obj) {
// did top value changed
if (i != 0 && $items.eq(i - 1).offset().top != $(obj).offset().top) {
reverse = !reverse;
// insert index when reverse
idx = i;
}
if (reverse) {
$order.splice(idx, 0, i);
} else {
$order.push(i);
}
});
// set item's order
$items.css('order', function(i, val) {
return $order[i];
});
}
// run at load
$.fn.setOrder(false,0);
}(jQuery));
.flexbox-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
width: 200px;
height: 100px;
background: red;
margin: 5px;
font-family: sans-serif;
color: white;
text-align: center;
font-size: 2em;
line-height: 150%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flexbox-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
#2
3
The only way I can see this happening is by manually setting the order and then using media queries for your breakpoints - here is an example
我能看到这种情况发生的唯一方法是手动设置订单,然后对断点使用媒体查询——这里有一个例子
.flexbox-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
width: calc(50% - 10px);
height: 100px;
background: red;
margin: 5px;
font-family: sans-serif;
color: white;
text-align: center;
font-size: 2em;
line-height: 150%;
}
.flex-item:nth-child(1) {
order: 1;
}
.flex-item:nth-child(2) {
order: 2;
}
.flex-item:nth-child(3) {
order: 4;
}
.flex-item:nth-child(4) {
order: 3;
}
.flex-item:nth-child(5) {
order: 5;
}
.flex-item:nth-child(6) {
order: 6;
}
.flex-item:nth-child(7) {
order: 8;
}
.flex-item:nth-child(8) {
order: 7;
}
@media only screen and (max-width: 768px) {
.flex-item {
width: calc(33.33333% - 10px);
}
.flex-item:nth-child(1) {
order: 1;
}
.flex-item:nth-child(2) {
order: 2;
}
.flex-item:nth-child(3) {
order: 3;
}
.flex-item:nth-child(4) {
order: 6;
}
.flex-item:nth-child(5) {
order: 5;
}
.flex-item:nth-child(6) {
order: 4;
}
.flex-item:nth-child(7) {
order: 7;
}
.flex-item:nth-child(8) {
order: 8;
}
<div class="flexbox-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>