【问题标题】:Child's `height: 100%;` is not taking parent's full height, why?孩子的`height: 100%;`没有取父母的全高,为什么?
【发布时间】:2020-12-09 09:04:08
【问题描述】:

父母和孩子都有box-sizing: border-box;。根据 MDN:

将高度定义为包含块高度的百分比。

那么孩子的身高也应该是500px,但显然不是,它有父母的内容高度不是 父母的高度。在包括 IE 在内的许多浏览器上尝试过这段代码,它们的工作原理都是一样的,这是为什么呢?

<!DOCTYPE html>
<html lang="zh-Hans">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css" />
    <title>Test</title>
    <style>
      body {
        background: #000;
      }
      .parent {
        border: 50px solid blue;
        padding: 20px;
        width: 500px;
        height: 500px;
        background: green;
        overflow: auto;
      }
      .child {
        background: red;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      <div class="child"></div>
    </div>
  </body>
</html>

【问题讨论】:

  • 因为您已经为parent 元素设置了padding: 20px,所以您的child div 没有达到100% 的高度。
  • 但是父级有box-sizing: border-box;,它的高度也包括填充,所以父级的高度仍然是500px,根据文档:“ 将高度定义为包含的百分比块的高度。”,孩子的高度应该是500px并溢出。
  • @Wenfang 是的,但没关系,事实上,相对于父级的内容,100% 更小。 (请记住,背景属性也会使填充着色!)
  • “但显然不是,它具有父级内容高度的高度,而不是父级的高度。” - 你引用的部分说它指的是 包含块 自己,developer.mozilla.org/en-US/docs/Web/CSS/Containing_block 解释说,“大多数情况下,包含块是元素最近的块级祖先的内容区域 […]” - 那么你在哪里看到任何这里的实际差异?
  • Yoshi 在他们的回答中解释得很好,看看吧。但是,如果您不希望您的元素受到其父级填充的限制,则将父级的位置设置为相对,将子级的位置设置为绝对,并将左侧和顶部设置为 0,但这也是不够的,它会导致子级的宽度和高度为 400px,因为父元素的边框将是子元素的限制

标签: html css


【解决方案1】:

使用border-box 只是定义给定高度应如何应用于填充和边框值。在您的示例中,这导致 .parent 的外部高度为 500px。

基本上这只是一种方便的方法 - 这样您就不必自己计算实际高度(就像在 border-box 出现之前的时代一样)。如果没有它,您需要定义 height: 360px; 以实现 500 像素的外部高度。

.child包含块 仍位于内部.parent 的填充分隔的区域内。百分比高度是相对于包含块 (ref) 计算的。在此示例中,与 .parent 上没有 border-box 时使用的 360px 相同。

【讨论】:

  • 很好解释,子元素将始终保留在父元素的内容区域内,并受其父元素的填充限制。
【解决方案2】:

如您所见,这是因为您为父级设置了填充。所以它的 100% 不会考虑填充。

body {
   background: #000;
}
.parent {
   border: 50px solid blue;
   padding: 20px;
   width: 500px;
   height: 500px;
   background: green;
   overflow: auto;
}
.child {
   background: red;
   height: 100%;
}
<div class="parent">
  <div class="child"></div>
</div>

目前尚不清楚您要做什么,但是如果您想让孩子填满整个父母,解决方案可能是这样的:

body {
   background: #000;
}
.parent {
   border: 50px solid blue;
   /* padding: 20px; simply remove the padding */
   width: 500px;
   height: 500px;
   background: green;
   overflow: auto;
}
.child {
   background: red;
   height: 100%;
}
<div class="parent">
  <div class="child"></div>
</div>

这是因为当属性box-sizing 设置为border-box 时,填充会从属性heightwidth... 中被考虑在内,但这并不意味着填充消失,填充只是作用于父级的内容。

记住这一点!

【讨论】:

  • 这个答案并没有真正解释为什么,它更像是展示行为,我要的是为什么。
  • 查看我最近的编辑,希望这可以更好地解释我的意思。
【解决方案3】:

看来我误解了 containing block 这个词,我以为它是父级,但不是真的,还有更多内容。

我不得不深入了解W3C standard 才能找到:

“包含块”的定义

元素框的位置和大小有时是相对于某个矩形计算的,称为元素的包含块

根元素所在的包含块是一个称为初始包含块的矩形。

对于其他元素,如果元素的位置是“相对”或“静态”,则包含块由最近的块容器祖先框的内容边缘形成。
...

【讨论】:

    【解决方案4】:

    因为您在父级中使用子 div,父级高度为 500 像素,而您使用子级高度 100 % 这就是为什么子级由于父级而获得 500 像素高度。

    【讨论】:

    • 请阅读描述并尝试代码,高度不是500px
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 2023-03-22
    相关资源
    最近更新 更多