【问题标题】:Best way to arrange labels and inputs side-by-side并排排列标签和输入的最佳方式
【发布时间】:2017-12-26 17:07:42
【问题描述】:

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

【问题讨论】:

  • 根据文档 (v4-alpha.getbootstrap.com/components/forms/#using-the-grid),您应该为此使用网格。哪些浏览器兼容性问题会阻止您使用 Grid,但仍然允许使用 Bootstrap v4?
  • 引导网格对我的需要来说太死板了。我需要第一列具有灵活的宽度。我不能只说 col-3 和 col-9。我的意思是我不想使用 display:grid 来与浏览器兼容。如果有引导网格解决方案,我愿意接受。
  • 你为什么不用一张桌子?您显然是在寻找表格的行为,所以我不会将其称为不好的做法。

标签: html twitter-bootstrap css flexbox


【解决方案1】:

align-items: stretch

Flexbox 有一个通常称为“等高列”的特性。此功能使同一容器中的弹性项目都具有相同的高度。

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

  • 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: columnflex-wrap: wrapheight

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

所以我们需要用wrap覆盖flex-wrap: nowrap(默认)。

此外,容器必须有一个固定的高度,以便物品知道在哪里包装。

参考资料:


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

【讨论】:

  • 谢谢@Michael_B。您的第一个解决方案是不可维护的,因为它手动设置容器的高度,并且每次添加或删除输入时都必须更改。但是,您的第二个解决方案效果很好。我不喜欢从输入中分解标签的想法,但它会起作用。已接受答案。
【解决方案2】:

我认为@Michael_B 的解决方案很棒,但另一种方法是创建一个包含 2 列的 flex 行,然后将每列设为 flex 列。只需在label/inputs 上设置一个高度,使它们保持一致,然后调整边距。

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

【讨论】:

  • 我在您的解决方案中看到的唯一问题是它无法在 xs 屏幕上运行
【解决方案3】:

我知道您说过您不需要 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-27
    • 2015-09-16
    • 2013-10-06
    • 1970-01-01
    • 2015-12-06
    • 1970-01-01
    • 2021-06-29
    • 2012-02-04
    相关资源
    最近更新 更多