不使用表格或display:table
,是否可以在输入左侧为标签设置灵活的宽度区域? 出于浏览器兼容性原因,我还想避免网格布局。 我希望 css 处理这个问题:
short_label input_box____________________
tiny_label input_box____________________
medium_label input_box____________________
然后相应地处理更大的标签:
short_label input_box__________
medium_label input_box__________
very_extra_long_label input_box__________
但我不想要:
short_label input_box__________
tiny_label input_box__________
medium_label input_box__________
因此,第一列需要具有灵活的宽度,第二列需要增长以填充空间。理想情况下,我的 html 看起来像这样,但如有必要,可以添加"行"div。 我觉得有一个灵活的答案,但也许不是,因为所有行都需要对齐。
<div class='aligned_form'>
<label for='a'>short_label</label>
<input type='text' id='a'>
<label for='b'>medium_label</label>
<input type='text' id='b'>
<label for='c'>very_extra_long_label</label>
<input type='text' id='c'>
</div>
align-items: stretch
弹性框具有通常称为"等高列"的功能。此功能使同一容器中的弹性项目高度相等。
此功能来自两个初始设置:
flex-direction: row
align-items: stretch
稍作修改,此功能即可变为"等宽行"。
flex-direction: column
align-items: stretch
现在,一列弹性项目将具有最长项目的宽度。
参考:
- 带弹性框的等高列
align-content: stretch
弹性容器上的初始设置为align-content: stretch
。此设置将在容器的长度上分布行或列(取决于flex-direction
(。
在这种情况下,为了将两列打包到容器的开头,我们需要用align-content: flex-start
覆盖默认值。
引用:
- 在多行弹性项目换行时删除它们之间的空间(间隙(
- 弹性换行如何与对齐、对齐项目和对齐内容配合使用?
flex-direction: column
、flex-wrap: wrap
和height
由于您具有首选的HTML结构(所有表单元素在一个容器中按逻辑顺序排序(,因此flex项目需要换行以形成标签列和输入列。
所以我们需要用wrap
覆盖flex-wrap: nowrap
(默认值(。
此外,容器必须具有固定高度,以便物品知道在哪里包装。
引用:
- 弹性项目是否可以与其上方的项目紧密对齐?
- 使div 跨越网格中的两行
order
属性
需要order
属性才能跨列正确对齐标签和输入。
参考:
- 是否有"前兄弟姐妹"CSS选择器?
.aligned_form {
display: flex;
flex-flow: column wrap;
align-content: flex-start;
height: 75px;
}
label[for='a'] { order: -3; }
label[for='b'] { order: -2; }
label[for='c'] { order: -1; }
label, input {
height: 25px;
padding: 5px;
box-sizing: border-box;
}
<!-- No changes to the HTML. -->
<div class='aligned_form'>
<label for='a'>short_label</label>
<input type='text' id='a' placeholder="short_label">
<label for='b'>medium_label</label>
<input type='text' id='b' placeholder="medium_label">
<label for='c'>very_extra_long_label</label>
<input type='text' id='c' placeholder="very_extra_long_label">
</div>
jsFiddle 演示 1
更改 HTML 结构
如果您可以更改 HTML,这里有一个替代解决方案。
- 一个主弹性容器,其中包含两个弹性项目列(标签和输入(
- 将
flex: 1
添加到输入列,以便它占用行中的所有可用空间,并将标签列打包到其最长项目的宽度
form {
display: flex;
}
form > div {
display: flex;
flex-direction: column;
}
form > div:last-child {
flex: 1;
}
label, input {
height: 25px;
padding: 5px;
box-sizing: border-box;
}
<form>
<div>
<label for='a'>short_label</label>
<label for='b'>medium_label</label>
<label for='c'>very_extra_long_label</label>
</div>
<div>
<input type='text' id='a' placeholder="short_label">
<input type='text' id='b' placeholder="medium_label">
<input type='text' id='c' placeholder="very_extra_long_label">
</div>
</form>
js小提琴演示 2
我知道你说你不想要CSS网格布局,但出于文档目的,我将在这里添加它。因为我认为如果您不介意支持问题,这是最干净的解决方案。
您始终可以通过将1fr
输入替换为像素或其他值来设置输入的固定宽度。此外,align-self
是将标签和输入垂直居中,如果您希望将center
更改为end
。 这也使HTML保持超级干净!
.container{
display: grid;
grid-gap: 10px;
grid-template-columns: [label] auto [input] 1fr;
}
input {
grid-column: input;
align-self: center;
}
label {
grid-column: label;
align-self: center;
}
<div class="container">
<label for='a'>short_label</label>
<input type='text' id='a'>
<label for='b'>medium_label</label>
<input type='text' id='b'>
<label for='c'>very_extra_long_label</label>
<input type='text' id='c'>
</div>
我认为@Michael_B的解决方案很棒,但另一种方法是创建一个包含 2 列的弹性行,然后将每一列都设为弹性列。只需在label/input
上设置一个高度,使它们保持一致,然后调整边距。
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<style>
label,input {
height: 25px;
margin:0 0 .5em;
}
label {
margin-right: .5em;
}
</style>
<div class="container">
<div class="row">
<div class="d-flex flex-column">
<label for='a'>short_label</label>
<label for='b'>medium_label</label>
<label for='c'>very_extra_long_label</label>
</div>
<div class="d-flex flex-column">
<input type='text' id='a'>
<input type='text' id='b'>
<input type='text' id='c'>
</div>
</div>
</div>