为什么输入字段宽度会随着输入数量(flexbox)的增加而增加?

Why does input field width grow with number of inputs (flexbox)?

我正在实现一个表单,该表单包含多个部分以及不同数量的输入字段。当在父 div 上使用 display: flex 并在输入字段上使用 100% 宽度时,我会计算出不同的宽度,具体取决于表单内输入字段的数量。

使用 display: block 时,一切正常。

<section>
  One input field.
  <div>
    <form action="">
      <input type="text">
    </form>
  </div>
</section>
<section>
  Two input fields.
  <div>
    <form action="">
      <input type="text"> <!-- each input field is double as wide as in the first section! -->
      <input type="text">
    </form>
  </div>
</section>
section {
  background: lightgrey;
  width: 1100px;
}

div {
  background: red;
  display: flex;
}

form {
  background: blue;
  box-sizing: border-box;
}

input {
  box-sizing: border-box;
  width: 100%;
  margin: 0.3125em 0 0.625em;
}

Codepen link with example

这应该是正常的 flexbox 行为吗?我错过了什么吗? 感谢您的帮助!

您在错误的元素上设置 display: flex CSS 属性,您需要在表单上设置而不是 div, 当您在 div 上设置 display: flex 时,它们的形式成为弹性项目而不是输入,因此 flex-item 行为的 none 进入输入字段。

跟随 CSS 它会正常工作

 section {
      background: lightgrey;
      width: 1000px;
    }

    div {
      background: red;
      display: flex;
    }

    form {
      background: blue;
      display:flex;
      box-sizing: border-box;
    }

    input {
      box-sizing: border-box;
      width: 100%;
      margin: 0.3125em 0 0.625em;
    }

详情请参考Flex tutorial

只需删除width:100%,您就会更好地理解:

section {
  background: lightgrey;
  width: 1000px;
}

div {
  background: red;
  display: flex;
}

form {
  background: blue;
  box-sizing: border-box;
}

input {
  box-sizing: border-box;
  margin: 0.3125em 0 0.625em;
}
<section>
  One input field.
  <div>
    <form action="">
      <input type="text">
    </form>
  </div>
</section>
<section>
  Two input fields.
  <div>
    <form action="">
      <input type="text">
      <input type="text">
    </form>
  </div>
</section>
<section>
  Three input fields.
  <div>
    <form action="">
      <input type="text">
      <input type="text">
      <input type="text">
    </form>
  </div>
</section>
<section>
  Four input fields.
  <div>
    <form action="">
      <input type="text">
      <input type="text">
      <input type="text">
      <input type="text">
    </form>
  </div>
</section>

输入定义了蓝色框的宽度,然后这个宽度将作为 width: 100%; 的参考,使所有输入成为它的全宽。


基本上,百分比值需要参考,因此首先根据内容计算蓝色框的宽度,然后输入将使用该宽度作为参考。

简单的 inline-block 元素也可能发生这种情况

section {
  background: lightgrey;
  width: 1000px;
}

div {
  background: red;
  display: inline-block;
}

form {
  background: blue;
  box-sizing: border-box;
}

input {
  box-sizing: border-box;
  width:100%;
  margin: 0.3125em 0 0.625em;
}
<section>
  <div>
    <form action="">
      <input type="text">
    </form>
  </div>
</section>
<section>
  <div>
    <form action="">
      <input type="text">
      <input type="text">
    </form>
  </div>
</section>
<section>
  <div>
    <form action="">
      <input type="text">
      <input type="text">
      <input type="text">
    </form>
  </div>
</section>
<section>
  <div>
    <form action="">
      <input type="text">
      <input type="text">
      <input type="text">
      <input type="text">
    </form>
  </div>
</section>

有关百分比调整的更多详细信息:https://www.w3.org/TR/css-sizing-3/#percentage-sizing

您可以找到此类行为的明确示例:

For example, in the following markup:

<article style="width: min-content">
  <aside style="width: 50%;">
  LOOOOOOOOOOOOOOOOOOOONG
  </aside>
</article>

When calculating the width of the outer <article>, the inner <aside> behaves as width: auto, so the <article> sets itself to the width of the long word. Since the <article>’s width didn’t depend on "real" layout, though, it’s treated as definite for resolving the <aside>, whose width resolves to half that of the <article>.


When using display: block, everything works as intended.

仅仅是因为块元素的宽度计算不同并且不依赖于内容,不像 inline-block 元素或内容定义宽度的弹性项目

在主容器 (div) 上使用 display: blockform 元素 – div 的 child – 自动占​​据 100% 宽度parent.

在主容器上使用 display: flexform 元素默认为 flex-basis: auto,这是其内容的宽度。

因此,如果您想要与 display: flex 相同的行为,请将 flex: 1 0 0(又名 flex: 1)添加到 form 元素。这告诉他们占据 parent 的全宽,例如 display: block.

section {
  background: lightgrey;
  width: 1000px;
}

div {
  background: red;
  display: flex;
}

form {
  flex: 1;  /* flex-grow: 1, flex-shrink: 1, flex-basis: 0 */
  background: blue;
  box-sizing: border-box;
}

input {
  box-sizing: border-box;
  width: 100%;
  margin: 0.3125em 0 0.625em;
}
<section>
  One input field.
  <div>
    <form action="">
      <input type="text">
    </form>
  </div>
</section>
<section>
  Two input fields.
  <div>
    <form action="">
      <input type="text">
      <input type="text">
    </form>
  </div>
</section>
<section>
  Three input fields.
  <div>
    <form action="">
      <input type="text">
      <input type="text">
      <input type="text">
    </form>
  </div>
</section>
<section>
  Four input fields.
  <div>
    <form action="">
      <input type="text">
      <input type="text">
      <input type="text">
      <input type="text">
    </form>
  </div>
</section>