我正在努力创建一个类似于Chosen的组件,但我遇到了flex和wrap问题。要点是每个"芯片"在伪文本框中需要在一个不包含实际文本输入的容器中,但我需要将这些芯片视为与input
相同的灵活元素。
我的HTML结构如下所示:
<div class="box">
<div class="chipContainer">
<div class="chip">Chip1</div>
<div class="chip">Chip2</div>
<div class="chip">Chip3</div>
<div class="chip">Chip4</div>
</div>
<input class="textbox" type="text">
</div>
此Plunker example更完整,风格大致相当于我目前使用的风格。
.box {
background: #fff;
border: 1px solid #ccc;
width: 500px;
overflow: auto;
padding: 2px;
display: flex;
flex-wrap: wrap;
}
.chip {
display: inline-block;
border: 1px solid #ccc;
background: #eee;
padding: 2px;
margin-right: 1px;
flex: auto;
}
.textbox {
border: none;
background: #fdd;
font-size: 18px;
flex: auto;
}
.textbox:focus {
outline: none;
}
.chipContainer {
display: inline;
}
&#13;
<div class="box">
<div class="chipContainer">
<div class="chip">Chip1</div>
<div class="chip">Chip2</div>
<div class="chip">Chip3</div>
<div class="chip">Chip4</div>
</div>
<input class="textbox" type="text">
</div>
<br>
<div class="box">
<div class="chipContainer">
<div class="chip">Chip1</div>
<div class="chip">Chip2</div>
<div class="chip">Chip3</div>
<div class="chip">Chip4</div>
<div class="chip">Chip5</div>
<div class="chip">Chip6</div>
<div class="chip">Chip7</div>
<div class="chip">Chip8</div>
<div class="chip">Chip9</div>
<div class="chip">Chip10</div>
<div class="chip">Chip11</div>
</div>
<input class="textbox" type="text">
</div>
&#13;
正如您所看到的,在.box
容器中添加了足够的筹码后,.chipContainer
将开始包装它们,但.chipContainer
仍然是一个块元素并推送{{1}完全降低到新的一行。
这Plunker example证明了我的目标。删除input
后,可以非常轻松地实现布局,但它在组件的结构中是一个相当重要的元素,如果可能,我宁愿在不删除的情况下解决此问题。
.chipContainer
&#13;
.box {
background: #fff;
border: 1px solid #ccc;
width: 500px;
overflow: auto;
padding: 2px;
display: flex;
flex-wrap: wrap;
}
.chip {
display: inline-block;
border: 1px solid #ccc;
background: #eee;
padding: 2px;
margin-right: 1px;
flex: auto;
min-width: 50px;
max-width: 60px;
}
.textbox {
border: none;
background: #fdd;
font-size: 18px;
flex: auto;
min-width: 250px;
}
.textbox:focus {
outline: none;
}
.chipContainer {
display: inline;
}
&#13;
答案 0 :(得分:4)
Display Module Level 3介绍display: contents
:
元素本身不生成任何框,但它的子元素和 伪元素仍然正常生成框。出于...的目的 框生成和布局,必须将元素视为具有 已被文档中的子元素和伪元素替换 树。
所以你需要
.chipContainer {
display: contents;
}
.box {
background: #fff;
border: 1px solid #ccc;
width: 500px;
overflow: auto;
padding: 2px;
display: flex;
flex-wrap: wrap;
}
.chip {
display: inline-block;
border: 1px solid #ccc;
background: #eee;
padding: 2px;
margin-right: 1px;
flex: auto;
min-width: 50px;
max-width: 60px;
}
.textbox {
border: none;
background: #fdd;
font-size: 18px;
flex: auto;
}
.textbox:focus {
outline: none;
}
.chipContainer {
display: contents;
}
<div class="box">
<div class="chipContainer">
<div class="chip">Chip1</div>
<div class="chip">Chip2</div>
<div class="chip">Chip3</div>
<div class="chip">Chip4</div>
</div>
<input class="textbox" type="text">
</div>
<br>
<div class="box">
<div class="chipContainer">
<div class="chip">Chip1</div>
<div class="chip">Chip2</div>
<div class="chip">Chip3</div>
<div class="chip">Chip4</div>
<div class="chip">Chip5</div>
<div class="chip">Chip6</div>
<div class="chip">Chip7</div>
<div class="chip">Chip8</div>
<div class="chip">Chip9</div>
<div class="chip">Chip10</div>
<div class="chip">Chip11</div>
</div>
<input class="textbox" type="text">
</div>
然而,请注意它尚未得到广泛支持。
答案 1 :(得分:0)
您可以使用flex-grow
和flex-basis
:
但是,这些属性的值应根据子元素.chipContainer
的数量而改变。
ideia是(使用您的示例),.chipContainer
是.box
的弹性项目,但也是其子项的弹性容器。作为弹性项目,它应该比.textbox
大4个大小,因为有.chip
个,因此我们使用flex-grow:4
和flex-basis:4px
。
.textbox
和.chip
应该具有相同的尺寸,因此所有这些都有flex-basis:1px
和flex-grow:1
。
.box, .chipContainer
{
display: flex;
}
.textbox, .chip
{
flex-grow: 1;
flex-basis: 1px;
border-width: 0;
}
.chipContainer
{
flex-grow: 4;
flex-basis: 4px;
}
<div class="box">
<div class="chipContainer">
<div class="chip">Chip1</div>
<div class="chip">Chip2</div>
<div class="chip">Chip3</div>
<div class="chip">Chip4</div>
</div>
<input type="text" class="textbox" />
</div>
这种方法的唯一问题是至少在Chrome上输入文本的边框使得计算失败并且比其他盒子多4个像素,我从所有项目中删除了边框,因此它们现在具有相同的宽度。