我可以使用CSS flexbox强制包装所有项目吗?

时间:2015-02-04 04:10:52

标签: css css3 flexbox

我有三个块元素,我用CSS Flexbox进行布局。 (就我而言,它们恰好是<select>s元素两侧的两个<div>ider;我正在构建一个List Builder控件。)

我想要的是:

  • 让中间(分隔符)元素占用尽可能少的空间。
  • 让两端的元素(即:选择控件)具有最小宽度,并增长以填充可能的空间。
  • 当容器中有足够的水平空间时(例如:浏览器宽度),将所有三个元素放在一行上
  • 全部时,如果没有足够的水平空间将这些元素水平放置,则元素会垂直包裹。

Flexbox在所有这些方面做得非常出色,除了以满足最后一项要求。如果没有足够的空间将所有元素放在一行上,我就不能强制所有元素进行换行。

我使用相当简单的flexbox设置来实现布局:

.container {
    display: flex;
    flex-wrap: wrap;
    flex-direction: row;
    align-items: center;
}

select {
    flex-basis: 10em;
    flex-grow: 1;
}

.divider {
    flex-basis: 3em;
    flex-grow: 0;
    text-align: center;
}

这个问题是,如果容器宽度被设置为对于一个选择加上分隔符足够宽的任何量,它将包装结束选择,但不是分隔符。我会在一行上得到一个选择加一个分隔符,看起来很难看。

这个小提琴说明了这个问题:

http://jsfiddle.net/5s0yf74w/1/

通过调整CSS同时保留一般的flexbox布局,可以实现我想要的结果吗?

2 个答案:

答案 0 :(得分:3)

如果没有基于JS的迭代布局逻辑(我知道,让浏览器渲染,计算宽度并有条件地添加/删除类),我认为没有你想要的东西是可能的。 但我认为this fiddle中给出的解决方案是一种理智的CSS方法。基本上有两种布局, wide ,其中我只做了一次更改flex-wrap: nowrap;,以防止你描述的不是所有三个元素被包裹的令人讨厌的情况。 narrow 覆盖了flex-direction: column;的flex方向。通过使用合理的min-width

来应用适当的媒体查询,可以轻松切换两者

答案 1 :(得分:1)

不完全是你所要求的,但(可能)甚至更好。 你可以设置它而不需要任何分隔符。你会在需要的时候得到分隔物的幻觉,但是当没有分隔物时你会得到分隔物

&#13;
&#13;
#wide {
    width: 31em;
}
#narrow {
    width: 10em;
  top: 100px;
}


.container {
  position: absolute;
   border: solid red 1px;
  background-image: radial-gradient(circle at center, blue 5px, transparent 5px);
}
.fakecontainer {
    display: flex;
    flex-wrap: wrap;
    flex-direction: row;
    align-items: center;
    margin-right: -1em;
}

select {
    flex-basis: 11em;
    flex-grow: 1;
    
    margin-right: 1em;
}

select:nth-child (2) {
    flex-basis: 10em;
  
}
&#13;
<div class="container" id="wide">
<div class="fakecontainer">
    <select multiple>
        <option>One of many</option>
        <option>Two of many</option>
    </select>
    <select multiple>
        <option>One of many</option>
        <option>Two of many</option>
    </select>
</div>
</div>
<div class="container" id="narrow">
<div class="fakecontainer">
    <select multiple>
        <option>One of many</option>
        <option>Two of many</option>
    </select>
    <select multiple>
        <option>One of many</option>
        <option>Two of many</option>
    </select>
</div>
</div>
&#13;
&#13;
&#13;

你只需要一个额外的元素,fakecontainer,用边缘做一些黑客

如果你真的想要在窄选项中使用分隔符,你只需要在底部边距做一个类似的技巧(如果是这种情况,请告诉我)