使用 flex order 属性为桌面和移动视图重新排列项目 [英] Using flex order property to re-arrange items for desktop and mobile views
问题描述
我在一个容器中有 3 个 div.没有嵌套的 div.
我正在使用 flex 和 order
属性.
在移动设备上,order
属性就可以了.
但在更大的屏幕上它会失败.
我没有为 div 2 和 3 使用容器 div,以便在移动设备上将它们排序为 2,1,3.
HTML 文件
<div class="orange">1</div><div class="blue">2</div><div class="green">3</div>
CSS 文件
/*************** 移动设备************/.容器{显示:弹性;flex-wrap: 包裹;}div.blue{订单:1;宽度:100%;}div.orange{订单:2;宽度:100%;}div.green{订单:3;宽度:100%;}/*****************************/@media 屏幕和(最小宽度:1200 像素){.容器{对齐内容:间隔;}div.blue{订单:2;宽度:36%;}div.orange{订单:1;宽度:60%;}div.green{订单:3;宽度:36%;}}
在您的布局中,将 row wrap
用于桌面视图将很难(如果不是不可能)通过 CSS 实现.至少,事情会变得过于复杂.为什么?
因为 flexbox 不是网格系统.这是一个布局系统,旨在通过容器中的空间分布来对齐内容.
在 flexbox 中,row wrap
容器中的项目必须换行到 新行.这意味着 div3 不能包裹在 div2 之下.它必须包裹在 div1 之下.
以下是使用 row wrap
将项目包裹在 flex 容器中的方式:
如果 div3 包裹在 div2 之下,那将不是 行,而是一个 网格,并且弹性项目被限制在一个笔直的、不弯曲的行中.
换句话说,你不能让一个 flex item 包裹在同一行的另一个 item 下.
因此,由不是行中最高的项目创建的空白会保留在每一列中,从而产生难看的间隙.
为了让你想要的布局在 row wrap
中工作,flex 项目必须退出它们的行以缩小间隙——也许是绝对定位——这是 flexbox 无法做到的.
对齐项目的一种方法是将 div2 和 div3 包装在它们自己的容器中.这个新容器将是 div1 的兄弟.然后它可以成为带有 flex-direction: column
的嵌套 flex 容器.现在差距消失了,布局看起来正确.
除了在这种特殊情况下,您需要 order
属性才能工作(意味着所有项目必须具有相同的父项),因此嵌套的 flex 容器是不可能的.
可能有效的是 column wrap
而不是 row wrap
:
/**************** MOBILE *************/.容器 {显示:弹性;弹性方向:列;高度:200px;/* 必要的所以项目知道在哪里包装 */}div.orange {背景颜色:橙色;}div.blue {顺序:-1;背景颜色:浅绿色;}div.green {背景颜色:浅绿色;}.container >div {宽度:100%;弹性:1;显示:弹性;对齐项目:居中;对齐内容:居中;}/*****************************/@media 屏幕和(最小宽度:800px){.容器 {flex-wrap: 包裹;}div.orange {弹性基础:100%;宽度:50%;}div.blue {弹性基础:50%;宽度:50%;订单:0;}div.green {弹性基础:50%;宽度:50%;}}
<div class="orange">1</div><div class="blue">2</div><div class="green">3</div>
jsFiddle
这里有另外两个选项:
- <块引用>
Masonry 是一个 JavaScript 网格布局库.它通过根据可用将元素放置在最佳位置来工作垂直空间,有点像石匠在墙上安装石头.
- <块引用>
这个 CSS 模块定义了一个基于二维网格的布局系统,针对用户界面设计进行了优化.在网格布局模型中,网格容器的子项可以放置在预定义的灵活或固定大小的布局网格中的任意槽中.
相关帖子:是否可以让 flex 项目与其上方的项目紧密对齐?
I have 3 divs inside a container. There are no nested divs.
I am using flex and order
property.
On mobile, it is ok with order
property.
But on larger screens it fails.
I did not use a container div for divs 2 and 3 in order to order them as 2,1,3 on mobile.
HTML FILE
<div class="container">
<div class="orange">1</div>
<div class="blue">2</div>
<div class="green">3</div>
</div>
CSS FILE
/*************** MOBILE *************/
.container
{
display: flex;
flex-wrap: wrap;
}
div.blue
{
order:1;
width: 100%;
}
div.orange
{
order:2;
width: 100%;
}
div.green
{
order:3;
width: 100%;
}
/***************************/
@media screen and (min-width:1200px)
{
.container
{
justify-content: space-between;
}
div.blue
{
order:2;
width: 36%;
}
div.orange
{
order:1;
width: 60%;
}
div.green
{
order:3;
width: 36%;
}
}
In your layout, using row wrap
for the desktop view will be difficult, if not impossible, to implement with CSS. At a minimum, things would get overly complex. Why?
Because flexbox is not a grid system. It's a layout system designed to align content by distribution of space in the container.
In flexbox, items in a row wrap
container must wrap to new rows. This means that div3 cannot wrap beneath div2. It must wrap beneath div1.
Here's how items wrap in a flex container with row wrap
:
If div3 were to wrap under div2, that wouldn't be a row, that would be a grid, and flex items are confined to a straight, unbending row.
Put another way, you can't make a flex item wrap under another item in the same row.
As a result, white space created by items that aren't the tallest in the row is preserved in each column, creating unsightly gaps.
For your desired layout to work in row wrap
, flex items would have to exit their row in order to close the gap – maybe with absolute positioning – which flexbox cannot do.
One way to align the items would be to wrap div2 and div3 in their own container. This new container would be a sibling to div1. It can then become a nested flex container with flex-direction: column
. Now the gaps are gone and layout looks right.
Except, in this particular case, you need the order
property to work (meaning all items must have the same parent), so a nested flex container is out of the question.
What may work is column wrap
instead of row wrap
:
/*************** MOBILE *************/
.container {
display: flex;
flex-direction: column;
height: 200px; /* necessary so items know where to wrap */
}
div.orange {
background-color: orange;
}
div.blue {
order: -1;
background-color: aqua;
}
div.green {
background-color: lightgreen;
}
.container > div {
width: 100%;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
/***************************/
@media screen and (min-width: 800px) {
.container {
flex-wrap: wrap;
}
div.orange {
flex-basis: 100%;
width: 50%;
}
div.blue {
flex-basis: 50%;
width: 50%;
order: 0;
}
div.green {
flex-basis: 50%;
width: 50%;
}
}
<div class="container">
<div class="orange">1</div>
<div class="blue">2</div>
<div class="green">3</div>
</div>
jsFiddle
Here are two other options:
Masonry is a JavaScript grid layout library. It works by placing elements in optimal position based on available vertical space, sort of like a mason fitting stones in a wall.
source: http://masonry.desandro.com/
CSS Grid Layout Module Level 1
This CSS module defines a two-dimensional grid-based layout system, optimized for user interface design. In the grid layout model, the children of a grid container can be positioned into arbitrary slots in a predefined flexible or fixed-size layout grid.
Related post: Is it possible for flex items to align tightly to the items above them?
这篇关于使用 flex order 属性为桌面和移动视图重新排列项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!