最好的方法来并排排列标签和输入

时间:2017-07-20 20:04:27

标签: html css twitter-bootstrap css3 flexbox

不使用表格或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>

3 个答案:

答案 0 :(得分:12)

align-items: stretch

Flexbox具有通常称为“相等高度列”的功能。此功能使同一容器中的柔性物品的高度均相等。

此功能来自两个初始设置:

  • flex-direction: row
  • align-items: stretch

稍作修改,此功能可以变为“等宽行”。

  • flex-direction: column
  • align-items: stretch

现在,一列flex项目将具有最长项目的宽度。

参考:

align-content: stretch

Flex容器的初始设置为align-content: stretch。此设置将在容器的长度上分配行或列(取决于flex-direction)。

在这种情况下,为了将两列打包到容器的开头,我们需要使用align-content: flex-start覆盖默认值。

参考文献:

flex-direction: columnflex-wrap: wrapheight

由于您有一个首选的HTML结构(所有表单元素在一个容器中按逻辑顺序排列),因此Flex项目需要换行以形成一列标签和一列输入。

因此,我们需要使用flex-wrap: nowrap覆盖wrap(默认值)。

此外,容器必须具有固定的高度,以便物品知道包裹的位置。

参考文献:

order属性

需要order属性才能正确对齐列间的标签和输入。

参考:

.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 demo 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>

jsFiddle demo 2

答案 1 :(得分:3)

我知道你说你不想要CSS Grid布局,但我会在这里添加它以用于文档目的。我认为如果您不介意支持问题,这是最干净的解决方案。

您可以通过将1fr替换为像素或其他值来为输入设置固定宽度。如果您更喜欢底部对齐的更改align-selfcenterend也会使标签居中并垂直输入。 这样可以保持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>

答案 2 :(得分:1)

我认为@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>