使用 flexbox 将网格从桌面调整到移动

Adjusting grid from desktop to mobile using flexbox

我正在尝试将桌面布局的内容作为优先事项,并根据客户的意愿将其重新流式传输到移动设备,但我无法完全让元素适合。这是桌面上的布局:

+----+----+
| 1  | 2  |
|    |    |
+---------+
| 3  | 4  |
|    | 5  |
+---------+

元素 4 和元素 5 包裹 div 在一起,因为它们的高度都是元素 3 的一半。桌面是优先​​事项,因此在开发时考虑到了这一点。以下是我想为移动设备实现的目标:

+----+----+
|    1    |
|         |
+---------+
| 4  | 2  |
| 5  | 3  |
+---------+

使用 flexbox 我设法重新定位了除 2 之外的所有元素。它只是换行到下一行。

我知道这并不理想,但是有什么方法可以让第二个元素排在第三个元素下面以形成 1x2 网格?

这是我接近的代码:

#wrapper { display: -webkit-flex; flex-wrap: wrap; align-content: stretch; }

#1 { order: 1; flex: 1 100%; }
#2 { order: 3; flex: 3 50%; }
#3 { order: 4; flex: 4 50%;  }
#4&5wrapper { order: 2; flex: 2 50%; }

这可能吗?

我相信你的问题的答案是否定的。原因如下:

桌面布局不是 flexbox 的问题。您只需将框 4 和框 5 包裹在嵌套的列方向弹性容器中,就大功告成了。

.inner-container {
    display: flex;
    flex-direction: column;
    order: 4;
    flex: 0 1 calc(50% - 10px - 2px); /* width less margin less borders */
}

但是,对于移动布局,它需要框 2 和 3 从外部弹性容器中的基于行的换行调整为内部弹性容器中的列方向堆栈(与框 4 和 5 一样) ,您需要更改加价。

在不更改标记的情况下,你能做的最好的(或者至少我能做的)是:

如果您有兴趣使用它,这里是演示中的代码:

HTML

<div class="outer-container">
    <span class="box box1">1</span>
    <span class="box box2">2</span>
    <span class="box box3">3</span>
    <div class="inner-container">
        <span class="box box4">4</span>
        <span class="box box5">5</span>
    </div>
</div>

CSS(包括非必需的装饰风格)

body { display: flex; align-items: flex-start; }

.outer-container {
    display: flex;
    flex-wrap: wrap;
    padding: 6px 0;
    background-color: #f5f5f5;
    border: 1px solid #ccc;
    width: 250px;
    box-sizing: border-box;
    margin-right: 15px;
}

.box {
    height: 100px;
    width: 50px;
    margin: 5px;
    background-color: lightgreen;
    border: 1px solid #ccc;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 1.2em;
}

.inner-container {
    display: flex;
    flex-direction: column;
    order: 4;
    flex: 0 1 calc(50% - 10px - 2px); /* width less margin less borders */
}

.box1 { flex: 0 1 calc(50% - 10px - 2px); order: 1; }
.box2 { flex: 0 1 calc(50% - 10px - 2px); order: 2; }
.box3 { flex: 0 1 calc(50% - 10px - 2px); order: 3; }
.box4 { flex: 0 1 calc(50% - 10px - 2px); width: 100%; }
.box5 { flex: 0 1 calc(50% - 10px - 2px); width: 100%; }

div.outer-container:last-of-type > .box1 { flex: 0 1 calc(100% - 10px - 2px); order: 1;}
div.outer-container:last-of-type > .inner-container { order: 2; margin-right: 10px; }
div.outer-container:last-of-type > .box2 { order: 3; }
div.outer-container:last-of-type > .box3 { order: 4; flex: 1 1 100%; }

演示版:http://jsfiddle.net/dLgjuyw6/1/ (Firefox)

编辑:刚注意到演示代码(如图所示)在 FF 中有效,但在 Chrome 中无效。由于此演示仅用于说明目的,与答案无关,因此我不追求浏览器兼容性。

- 已更新 -

答案是,

...但有一些技巧,也许不是您可能喜欢的并排 2 个柔性包装器的弯曲。将问题一分为二,一个常规的 flex 容器 (1&2&3) 和第二个 (4&5) 的一些相对定位,您将获得所需的布局。

我不确定这是最好的做法,甚至不确定这是您想要的答案,但也许这正是您所需要的。

请查看代码段并告诉我!

/* Global stuff */
html, body  { box-sizing: border-box; height: 100%; width: 100%;
              margin: 0; padding: 0; border: 0 }
*, *:before,
*:after     { box-sizing: inherit }

/* Solution */
#w1         { display: flex; 
              flex-flow: column wrap;    /* vertical arrangement */
              align-items: flex-end;     /* forces 2&3 to lower right */
              with: 100%; height: 100% } /* full screen */

#i1         { width: 100%; height: 50% } /* full width, half height of #w1 */
#i2,#i3     { width:  50%; height: 25% } /* half width, half height of #w1 */

#w2         { display: flex; flex-direction: column;/* stay unchanged */
              position: absolute; top: 50%;         /* nasty, but works */
              width:  50%; height: 50% }            /* stay unchanged */

#i4,#i5     { width: 100%; height: 50%  }           /* stay unchanged */

#i1::before { content: 'mobile '}

@media all and (min-width: 720px) {

    #i1::before { content: 'desktop '}

    /* become equal in size */
    #i1,#i2,#i3 { width:  50%; height: 50% }    /* half width, half height of #w1 */

    #w1         { flex-flow: row wrap;          /* horizontal arrangement */
                  justify: content: flex-start }/* forces 1&2&3 to upper left */   
    #w2         { right: 0 }                    /* reposition, nasty, but works */
}      

/* Demo */
#w1 *, #w2 *    { text-align: center; font-size: 40px; font-weight: bold;
                  background: #f0f0f0; border: 2px solid black }
<div id="w1">
    <div id="i1">1</div>
    <div id="i2">2</div>
    <div id="i3">3</div>
</div>

<div id="w2">
    <div id="i4">4</div>
    <div id="i5">5</div>
</div>

我知道您已经接受了“否”作为答案,但我还不确定。

我认为以下解决方案可以回答问题。请注意,我选择了 flex-bases(?) 以便它们的总和为 100%,但您不必这样做。这样就有一些余地来适应内容。

要查看会发生什么情况,请全屏观看解决方案并将浏览器 window 缩小(< 600 像素)。或者在 codepen.

上观看

    #one {background: lightblue;}   
    #two {background: skyblue;}   
    #three {background: blue;}   
    #four {background: aqua;}   
    #five {background: lime;}   
    div {flex: 1;}
    #wrapper {width: 100%; height: 95vh; border: 1px solid;}
    @media (min-width:600px){
        #wrapper {
            display: flex;
            flex-flow: column wrap;
            padding: 0;
            margin: 0;
        }
        div {width: 50%;}
        #one{
            order: 1;
            flex-basis: 66%;
        }
        #two{
            order: 2;
            flex-basis: 66%;
        }
        #three{
            order: 1;
            flex-basis: 34%;
        }
        #four{
            order: 2;
            flex-basis: 17%;
        }
        #five{
            order: 2;
            flex-basis: 17%
        }
    }
    @media (max-width:599px){
        #wrapper {
            display: flex;
            flex-flow: row wrap;
            padding: 0;
            margin: 0;
        }
        #one{
            order: 1;
            flex-basis: 100%;
            min-height: 40vh;
        }
        #two{
            order: 3;
            flex-basis: 50%;
        }
        #three{
            order: 5;
            flex-basis: 50%;
        }
        #four{
            order: 2;
            flex-basis: 50%;
        }
        #five{
            order: 4;
            flex-basis: 50%
        }
        
    }
 <div id='wrapper'>
        <div id='one'>1</div>
        <div id='two'>2</div>
        <div id='three'>3</div>
        <div id='four'>4</div>
        <div id='five'>5</div>
    </div>