使某些项目沿着横向轴堆叠在仅具有CSS的flex布局的行/列内 [英] Have certain items stack along the cross axis within a row/column of a flex layout with only CSS

查看:145
本文介绍了使某些项目沿着横向轴堆叠在仅具有CSS的flex布局的行/列内的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一次,我玩弄了一个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容器



但是如果你想要一个容器,你仍然可以这样做:

  • 6和7的宽度是已知的

  • 2,3和4的高度是已知的



  • 然后,您可以






    •  ┌─┬─┬─┬─┬─┬─┬─┐
      │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. Use flex-grow: 1 on the other ones.

      ┌─────────┬─┐
      │    1    │6│
      ├───┬───┬─┴─┤
      │ 2 │ 3 │ 4 │
      ├───┴───┴─┬─┤
      │    5    │7│
      └─────────┴─┘
      

    • Set the desired with, w, to 6 and 7. Add margin-right: w to 4

      ┌─────┬───┐
      │  1  │ 6 │
      ├─┬─┬─┼───┘
      │2│3│4│
      ├─┴─┴─┼───┐
      │  5  │ 7 │
      └─────┴───┘
      

    • Set the desired height, h, to 2, 3 and 4. Add margin-bottom: -h/2 to 6, and margin-top: -h/2 to 7.

      ┌─────┬───┐
      │  1  │ 6 │
      ├─┬─┬─┤   │
      │2│3│4├───┤
      ├─┴─┴─┤ 7 │
      │  5  │   │
      └─────┴───┘
      

    • Additionally, it might be a good idea adding a width or max-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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆