使某些项目沿着横向轴堆叠在仅具有CSS的flex布局的行/列内 [英] Have certain items stack along the cross axis within a row/column of a flex layout with only CSS
问题描述
有一次,我玩弄了一个CSS规范的建议,但后来我发现可能已经有一个我缺少的解决方案。我所说的布局类型的例子看起来像这样:
+ ------- ---- + --- +
| 1 | 6 |
+ --- + --- + --- + |
| 2 | 3 | 4 + --- +
+ --- + --- + --- + 7 |
| 5 | |
+ ----------- + --- +
问题是那些在左列中间的三个框沿着横轴堆叠,我找不到一个机制在CSS中做到这一点。我知道这可以做一个div包裹在这3个项目是一个行方向flex布局,但是这种方法打破了flex布局的灵活性,因为这些项目不能再重新排序外部布局和列/行间断不能再发生在它们之间。
HTML:
pre>< div id =flex-layout>
< div id =item1> 1< / div>
< div id =item2> 2< / div>
< div id =item3> 3< / div>
< div id =item4> 4< / div>
< div id =item5> 5< / div>
< div id =item6> 6< / div>
< div id =item7> 7< / div>
< / div>
CSS:
code>#flex-layout {
display:flex;
flex-direction:column;
height:300px;
width:400px;
flex-wrap:wrap;
align-items:stretch;
}
#item1 {
flex:0 0 100px;
width:300px;
}
#item2 {
flex:0 0 100px;
width:100px;
}
#item3 {
flex:0 0 100px;
width:100px;
}
#item4 {
flex:0 0 100px;
width:100px;
}
#item5 {
flex:0 0 100px;
}
#item6 {
flex:0 0 150px;
width:100px;
}
#item7 {
flex:0 0 150px;
}
使用多个flex容器
但是如果你想要一个容器,你仍然可以这样做:
然后,您可以
-
┌─┬─┬─┬─┬─┬─┬─┐
│1│2│3│4 │5│6│7│
└─┴─┴─┴-┴─┴─┴─┘
-
重新排列flex项目:1,6,2,3,4,5,7
┌─┬─┬─┬─┬─┬─┬─┐
│1│6│2│3│4│5│7│
└─┴─┴ ─┴─┴─┴─┴─┘
-
允许换行符
flex-wrap:wrap
-
使用伪元素在2和4之后强制换行。
┌─┬─┐
│1│6│
├─┼─┼ ─┐
│2│3│4│
├─┼─┼─┘
│5│7│
└─┴─┘
-
在6和7上使用
flex-grow:0
code> flex-grow:1 。┌───────┬┐┐┐
│1│6│
├───┬──┬┴┴┤┤┤
│2│3 │4│
├───┴──┴┬┬┤┤┤
│5│7│
└───────┴┴┘
-
使用
w
和7.将margin-right:w
添加到4┌────┬───┐
│1│6│
├─┬─┬─┼───┘
│2│3│4 │
├─┴─┴─┼───┐
│5││
└────┴───┘
-
将所需的高度
h
设置为2,3和4.添加margin-bottom:-h / 2
至6,margin-top:-h / 2
/ p>
┌────┬┬──┐
│1│6│
├─┬─┬─┤│
│2│3│4├───┤
├─┴─┴─┤7│
│5││
└────┴───┘
-
一个好主意将
width
或max-width
添加到2,3,4。
这里是代码:
#flex-layout {display: / * Magic starts * / flex-wrap:wrap; / * Multiline * /}#item1 {order:1; }#item6 {order:2; }#item2 {order:3; }#item3 {order:4; }#item4 {order:5; }#item5 {order:6; }#item7 {order:7; }#flex-layout> div {border:1px solid; box-sizing:border-box;}#item2,#item3,#item4 {height:50px; / * h * /}#item6 {margin-bottom:-25px; / * -h / 2 * /}#item7 {margin-top:-25px; / * -h / 2 * /}#item1,#item2,#item3,#item4,#item5 {flex-grow:1;}#item6,#item7 {width:25%; / * w * / flex-grow:0;}#item4 {margin-right:25%; / * w * /}#flex-layout:before {/ *强制换行前#item2 * / content:'';宽度:100%;顺序:3;}#flex-layout:after {/ *强制换行后#item4 * / content:'';宽度:100%; order:5;}
< div id = -layout> < div id =item1> 1< / div> < div id =item2> 2< / div> < div id =item3> 3< / div> < div id =item4> 4< / div> < div id =item5> 5< / div> < div id =item6> 6< / div> < div id =item7> 7< / div>< / div>
At one point I was toying with a CSS spec suggestion for this, but then I figured there is probably already a solution that I am missing. An example of the kind of layout I'm talking about would look something like this:
+-----------+---+
| 1 | 6 |
+---+---+---+ |
| 2 | 3 | 4 +---+
+---+---+---+ 7 |
| 5 | |
+-----------+---+
The problem is those three boxes in the middle of the left column are stacked along the cross axis, and I can't find a mechanism in CSS to do this. I know this could be done with a div wrapped around those 3 items that is a row direction flex layout, but that approach breaks the flexibility of a flex layout because those items can no longer be re-ordered around the outer layout and a column/row break can no longer happen between them. So, how can this be achieved this with only CSS, so that the flex layout stays flexable?
HTML:
<div id="flex-layout">
<div id="item1">1</div>
<div id="item2">2</div>
<div id="item3">3</div>
<div id="item4">4</div>
<div id="item5">5</div>
<div id="item6">6</div>
<div id="item7">7</div>
</div>
CSS:
#flex-layout {
display: flex;
flex-direction: column;
height: 300px;
width: 400px;
flex-wrap: wrap;
align-items: stretch;
}
#item1 {
flex: 0 0 100px;
width: 300px;
}
#item2 {
flex: 0 0 100px;
width: 100px;
}
#item3 {
flex: 0 0 100px;
width: 100px;
}
#item4 {
flex: 0 0 100px;
width: 100px;
}
#item5 {
flex: 0 0 100px;
}
#item6 {
flex: 0 0 150px;
width: 100px;
}
#item7 {
flex: 0 0 150px;
}
Using multiple flex containers would be easier.
But if you want a single container, you can still do it, with those assumptions:
- The width of 6 and 7 is known
- The height of 2, 3 and 4 is known
Then, you can
Use a row layout
┌─┬─┬─┬─┬─┬─┬─┐ │1│2│3│4│5│6│7│ └─┴─┴─┴─┴─┴─┴─┘
Reorder the flex items: 1,6,2,3,4,5,7
┌─┬─┬─┬─┬─┬─┬─┐ │1│6│2│3│4│5│7│ └─┴─┴─┴─┴─┴─┴─┘
Allow line breaks with
flex-wrap: wrap
.Use pseudo elements to force a line break before 2 and after 4
┌─┬─┐ │1│6│ ├─┼─┼─┐ │2│3│4│ ├─┼─┼─┘ │5│7│ └─┴─┘
Use
flex-grow: 0
on 6 and 7. Useflex-grow: 1
on the other ones.┌─────────┬─┐ │ 1 │6│ ├───┬───┬─┴─┤ │ 2 │ 3 │ 4 │ ├───┴───┴─┬─┤ │ 5 │7│ └─────────┴─┘
Set the desired with,
w
, to 6 and 7. Addmargin-right: w
to 4┌─────┬───┐ │ 1 │ 6 │ ├─┬─┬─┼───┘ │2│3│4│ ├─┴─┴─┼───┐ │ 5 │ 7 │ └─────┴───┘
Set the desired height,
h
, to 2, 3 and 4. Addmargin-bottom: -h/2
to 6, andmargin-top: -h/2
to 7.┌─────┬───┐ │ 1 │ 6 │ ├─┬─┬─┤ │ │2│3│4├───┤ ├─┴─┴─┤ 7 │ │ 5 │ │ └─────┴───┘
Additionally, it might be a good idea adding a
width
ormax-width
to 2,3,4. Otherwise, if their content is wide enough, they will be placed in different lines, breaking the layout.
Here is the code:
#flex-layout {
display: flex; /* Magic begins */
flex-wrap: wrap; /* Multiline */
}
#item1 { order: 1; }
#item6 { order: 2; }
#item2 { order: 3; }
#item3 { order: 4; }
#item4 { order: 5; }
#item5 { order: 6; }
#item7 { order: 7; }
#flex-layout > div {
border: 1px solid;
box-sizing: border-box;
}
#item2, #item3, #item4 {
height: 50px; /* h */
}
#item6 {
margin-bottom: -25px; /* -h/2 */
}
#item7 {
margin-top: -25px; /* -h/2 */
}
#item1, #item2, #item3, #item4, #item5 {
flex-grow: 1;
}
#item6, #item7 {
width: 25%; /* w */
flex-grow: 0;
}
#item4 {
margin-right: 25%; /* w */
}
#flex-layout:before {
/* Force line break before #item2 */
content: '';
width: 100%;
order: 3;
}
#flex-layout:after {
/* Force line break after #item4 */
content: '';
width: 100%;
order: 5;
}
<div id="flex-layout">
<div id="item1">1</div>
<div id="item2">2</div>
<div id="item3">3</div>
<div id="item4">4</div>
<div id="item5">5</div>
<div id="item6">6</div>
<div id="item7">7</div>
</div>
这篇关于使某些项目沿着横向轴堆叠在仅具有CSS的flex布局的行/列内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!