我可以用 CSS flexbox 强制包装所有项目吗?
Can I force wrapping of all items with CSS flexbox?
我用 CSS Flexbox 布置了三个块元素。 (在我的例子中,它们恰好是 <div>ider
元素两侧的两个 <select>s
;我正在构建一个 List Builder 控件。)
我想要的是:
- 让中间(分隔线)元素占用尽可能少的 space。
- 让两端的元素(即:select 控件)具有最小宽度,并增长以填充可能的 space。
- 当容器中有足够的水平 space(例如:浏览器宽度)时,将所有三个元素放在一行上
- 要让 所有 元素在没有足够的水平 space 水平放置它们时垂直环绕。
Flexbox 在所有这些方面都做得很好,除了 最后一个要求。如果 space 不足以将所有元素放在一行中,我无法强制 所有 元素换行。
我使用相当简单的 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;
}
问题在于,如果容器宽度设置为足以容纳一个 select 加上分隔线的任意数量,它将包裹末端 select,但 不是分隔线。我会得到一个 select 加一条线的分隔线,看起来很难看。
这个fiddle说明了这个问题:
http://jsfiddle.net/5s0yf74w/1/
是否可以在保留一般 flexbox 布局的同时调整 CSS 来达到我想要的结果?
我不认为如果没有基于 JS 的迭代布局逻辑(你知道,让浏览器呈现、计算宽度并有条件地添加/删除 类),你想要的东西是不可能的。
然而,我认为 this fiddle 中给出的解决方案是一种明智的 CSS 方法。基本上有两种布局,wide 一种我只做了一处更改 flex-wrap: nowrap;
以防止您描述的不是所有三个元素都被包裹的讨厌情况。 narrow 将 flex-direction 覆盖为 flex-direction: column;
。两者都可以通过使用合理的 min-width
.
应用适当的媒体查询轻松切换
不完全是您的要求,但(可能)更好。
您可以在没有任何分隔符的情况下进行设置。需要时你会得到分隔线的错觉,但不需要时没有分隔线
#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;
}
<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>
您只需要一个额外的元素 fakecontainer 来处理边距
如果你真的想要窄选项中的分隔线,你只需要对底部边距做一个类似的技巧(如果是这种情况请告诉我)
我用 CSS Flexbox 布置了三个块元素。 (在我的例子中,它们恰好是 <div>ider
元素两侧的两个 <select>s
;我正在构建一个 List Builder 控件。)
我想要的是:
- 让中间(分隔线)元素占用尽可能少的 space。
- 让两端的元素(即:select 控件)具有最小宽度,并增长以填充可能的 space。
- 当容器中有足够的水平 space(例如:浏览器宽度)时,将所有三个元素放在一行上
- 要让 所有 元素在没有足够的水平 space 水平放置它们时垂直环绕。
Flexbox 在所有这些方面都做得很好,除了 最后一个要求。如果 space 不足以将所有元素放在一行中,我无法强制 所有 元素换行。
我使用相当简单的 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;
}
问题在于,如果容器宽度设置为足以容纳一个 select 加上分隔线的任意数量,它将包裹末端 select,但 不是分隔线。我会得到一个 select 加一条线的分隔线,看起来很难看。
这个fiddle说明了这个问题:
http://jsfiddle.net/5s0yf74w/1/
是否可以在保留一般 flexbox 布局的同时调整 CSS 来达到我想要的结果?
我不认为如果没有基于 JS 的迭代布局逻辑(你知道,让浏览器呈现、计算宽度并有条件地添加/删除 类),你想要的东西是不可能的。
然而,我认为 this fiddle 中给出的解决方案是一种明智的 CSS 方法。基本上有两种布局,wide 一种我只做了一处更改 flex-wrap: nowrap;
以防止您描述的不是所有三个元素都被包裹的讨厌情况。 narrow 将 flex-direction 覆盖为 flex-direction: column;
。两者都可以通过使用合理的 min-width
.
不完全是您的要求,但(可能)更好。 您可以在没有任何分隔符的情况下进行设置。需要时你会得到分隔线的错觉,但不需要时没有分隔线
#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;
}
<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>
您只需要一个额外的元素 fakecontainer 来处理边距
如果你真的想要窄选项中的分隔线,你只需要对底部边距做一个类似的技巧(如果是这种情况请告诉我)