CSS高度设置为百分比,它是否相对于父内容框,或填充框等



MDN说:

The percentage is calculated with respect to the height of the generated box's containing block.
所以我们有一个包含子元素的包含块。子元素具有height: 100%或其他百分比。

如果包含块有高度,填充和边界设置,子元素的高度是否计算为包含块的内容盒高度,填充盒高度,边界盒高度的100% ?

如果我们改变了容器块的box-sizing,但也做了其他的改变,使得容器块的content-box/padding-box/border-box的大小没有改变,子元素的大小会受到影响吗?

编辑:显然padding-box是实验性的,只有FF支持。

基于%的子元素大小确实是根据父元素的大小计算的,并且它确实考虑了box-sizing

看这个演示:

.box {
  width: 100px;
  height: 100px;
  
  padding: 10px;
  margin: 10px;
  border: 10px solid black;
  
  background-color: red;
  color: white;
}
.content-box {
  box-sizing: content-box;
}
.border-box {
  box-sizing: border-box;
}
.child {
  width: 100%;
  height: 100%;
  background-color: blue;
}
<body>
  <div class="box content-box">
    <div class="child">Content Box</div>
  </div>
  
  <br/>
  <div class="box border-box">
    <div class="child">Border Box</div>
  </div>
</body>

当使用percent指定元素的高度时,该百分比与元素的包含块的高度相关。根据某些因素(参见下面的引语),包含块可以由元素父元素的内容边或填充边构成。换句话说,它不总是与父元素的内容边相关。

改变元素父元素的box-sizing本身不会影响元素的包含块,因此它不会改变子元素的大小。然而,在Khalos的代码片段中,父元素的内容边改变了,因此子元素的大小也随之改变。在该代码片段中,子元素的大小改变了,因为父元素的内容边改变了,而不是因为父元素的box-sizing改变了。(我知道对其他答案的评论不应该出现在这里,但我没有足够的声望点来在适当的位置评论它。)

关于元素的包含块的定义,请参阅W3C规范的这一部分。为完整起见,下面引用了该定义的摘录:

元素框(box)的位置和大小有时是相对于某个矩形(称为元素的包含块)计算的。元素的包含块定义如下:
  1. 根元素所在的包含块是一个矩形,称为初始包含块。对于连续介质,它具有视口的尺寸,并锚定在画布原点;它是分页媒体的页面区域。首字母的"方向"属性

  2. 对于其他元素,如果元素的位置为'相对'或'静态',则包含块由最近的块容器祖先盒的内容边形成。

  3. 如果元素具有'position: fixed',则包含块在连续媒体的情况下由视口建立,在分页媒体的情况下由页面区域建立。
  4. 如果元素具有'position: absolute',则包含该元素的块由最近的祖先以'position'为'absolute', 'relative'或'fixed'建立,方式如下:
    1. 如果父元素是内联元素,则包含块是围绕为该元素生成的第一个和最后一个内联框的填充框的边界框。在css2.1中,如果行内元素被分成多行,则包含的块是未定义的。

如果没有这样的祖先,则包含块为初始包含块。

答案不完整。有两种情况需要考虑:

  1. 没有应用绝对位置
  2. 绝对位置应用于子

没有应用绝对位置

百分比根据父节点设置高度计算。当应用box-sizing border-box时,这是根据设置的高度计算的,不包括父元素的填充和边框。因此,更准确地说,只有当父元素的高度设置为时,才能从content-area 中计算百分比高度。

如果父元素没有设置高度,而是初始默认值,即height auto,则浏览器将不会获取父元素计算出的自动高度的百分比。(Height auto表示元素的高度会自动拉伸,以适应通常需要的内容。)

演示:

.parent1, .parent2, .parent3 {
    width: 200px;
    background-color: crimson;
    margin: 10px;
}
.parent2 {
    min-height: 200px;
}
.parent3 {
    height: 200px;
}
.child {
    height: 50%;
    border: 4px solid black;
}
<div class="parent1">
    parent with<code>height: auto</code>
    <div class="child">
        child with <code>height: 50%</code> doesn't work
    </div>
</div>
<div class="parent2">
    parent with<br><code>min-height: 200px</code>
    <div class="child">
        child with <code>height: 50%</code> doesn't work
    </div>
</div>
<div class="parent3">
    parent with<br><code>height: 200px</code>
    <div class="child">
        child with <code>height: 50%</code>. it works!
    </div>
</div>

应用于子

的绝对位置

当将绝对位置应用于子元素时,总是应用百分比的高度,并从上下文的高度计算,也称为包含块。为了建立上下文,浏览器检查从parent到root的祖先链,使用位置相对、绝对、固定或sticky的第一个("最近的")祖先作为上下文。如果没有找到这样的祖先,则视口被用作上下文。

要使用父元素作为上下文并将其留在正常的文档流中,只需应用相对于父元素的位置。

.parent1, .parent2, .parent3 {
    width: 200px;
    background-color: crimson;
    margin: 10px;
}
.parent2 {
    position: relative;
}
.parent3 {
    height: 200px;
}
.child {
    height: 50%;
    border: 4px solid black;
}
.child2 {
    position: absolute;
}
<div class="parent1">
    parent with <code>height: auto</code> and no positioning.<br>
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim, recusandae quis modi tenetur ut blanditiis quaerat eius nisi beatae dignissimos? Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim, recusandae quis modi tenetur ut blanditiis quaerat eius nisi beatae dignissimos?
    <div class="child">
        child with <code>height: 50%</code> doesn't work
    </div>
</div>
<div class="parent2">
    parent with <code>height: auto</code> and  <code>position: relative</code>.<br>
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim, recusandae quis modi tenetur ut blanditiis quaerat eius nisi beatae dignissimos? Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim, recusandae quis modi tenetur ut blanditiis quaerat eius nisi beatae dignissimos?
    <div class="child child2">
        child with <code>height: 50%</code> and position: absolute. It works!
    </div>
</div>

最新更新