为什么子元素的填充会扩展父级元素的宽度?

3
考虑以下例子:

body {
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
  color:    #C0C0C0;
  background-color: #202020;
  display: flex;
  flex-direction: column;
  align-items: center;
}

* {
  box-sizing: border-box;
}
.col {
  display: flex;
  flex-direction: column;
}
.row {
  display: flex;
  flex-direction: row;
  background-color: gray
}
.wrap {
  flex-wrap: wrap;
}
.align-center {
  align-items: center;
}
.justify-center {
  justify-content: center;
}
.gap {
  gap: 20px;
}
input {
  background-color:#202020 ;
  border: 1px solid #C0C0C0 ;
  border-radius: 5px;
  padding: 12px 20px;
  margin: 8px 0;
  box-sizing: border-box;
}
.inputContainer {
  max-width: 300px;
  width: 100%;
}
.inputContainer > * {
  width: 100%;
}
<form class="col gap align-center" style="width: 90vw" action="">
  <div class="row wrap gap justify-center">
    <div class="col inputContainer">
      <label>expands:</label>
      <input />
    </div>
    <div class="col inputContainer">
      <label>parent:</label>
      <input />
    </div>
  </div>
  <div class="row wrap justify-center">
    <div class="col inputContainer">
      <label>even if:</label>
      <input />
    </div>
    <div class="col inputContainer">
      <label>no gap set:</label>
      <input />
    </div>
  </div>
  <div class="row wrap gap justify-center">
    <div class="col inputContainer">
      <label>alone works:</label>
      <input />
    </div>
  </div>
  <div class="row wrap gap justify-center">
    <div class="col inputContainer">
      <label>also with:</label>
      <input style='padding: 0' />
    </div>
    <div class="col inputContainer">
      <label>no padding:</label>
      <input style='padding: 0' />
    </div>
  </div>
</form>

灰色背景展示了每一行的尺寸。如果行内元素在x轴上有padding,即使box-sizing是border-box,它也会扩展父元素的宽度。如果该行只有一个子元素,那么就没有问题。如果子元素没有设置padding,也没有问题。但是如果子元素设置了padding,就会扩展父元素的宽度。为什么呢?

1个回答

2
一个复杂的收缩适应行为案例。所有的行都是弹性项,所以它们的宽度取决于它们的内容。现在复杂的部分是你让子元素有“width:100%”,这意味着父元素的100%宽度,所以我们在此形成了一个循环。
在这种情况下,浏览器将执行以下操作:
  1. 忽略“width:100%”(将其视为自动)
  2. 使用其他属性查找子元素的宽度
  3. 根据(2)设置父元素的宽度
  4. 基于(3)中找到的宽度来解决“width:100%”
  5. 子元素的宽度可能会改变,但父元素的宽度不会改变。
如果一个子元素是100%,那么逻辑上两者都不能放在同一行,每个子元素都将在自己的一行上。
以下是一个简单的两步说明来理解发生了什么:

body {
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
  color:    #C0C0C0;
  background-color: #202020;
  display: flex;
  flex-direction: column;
  align-items: center;
}

* {
  box-sizing: border-box;
}
.col {
  display: flex;
  flex-direction: column;
}
.row {
  display: flex;
  flex-direction: row;
  background-color: gray
}
.wrap {
  flex-wrap: wrap;
}
.align-center {
  align-items: center;
}
.justify-center {
  justify-content: center;
}
.gap {
  gap: 20px;
}
input {
  background-color:#202020 ;
  border: 1px solid #C0C0C0 ;
  border-radius: 5px;
  padding: 12px 20px;
  margin: 8px 0;
  box-sizing: border-box;
}
.inputContainer {
  max-width: 300px;
  width: 100%;
}
.inputContainer > * {
  width: 100%;
}
<form class="col gap align-center" style="width: 90vw" action="">
  <div class="row wrap gap justify-center">
    <div class="col inputContainer" style="width:auto">
      <label>expands:</label>
      <input />
    </div>
    <div class="col inputContainer" style="width:auto">
      <label>parent:</label>
      <input />
    </div>
  </div>
</form>
<hr>
<form class="col gap align-center" style="width: 90vw" action="">
  <div class="row wrap gap justify-center">
    <div class="col inputContainer" >
      <label>expands:</label>
      <input />
    </div>
    <div class="col inputContainer">
      <label>parent:</label>
      <input />
    </div>
  </div>
</form>

注意,在这两种情况下,父元素的宽度保持不变,而子元素的宽度是基于 width:auto 的。现在你可以轻松理解所有其他情况,特别是为什么添加填充会增加父元素的宽度。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接