高级渲染在Chrome和Firefox中有所不同

Jam*_*ang 20 html css css3 language-lawyer flexbox

我发现如果我们设置一个块级别元素,有height:autoheight: 0~100%没有设置父级的高度具有显式值,并且其块级别子级具有底部边距,那么它将在Chrome中以不同方式计算高度,但在Firefox中则不同.对于设置的情况height: 1%:

http://codepen.io/anon/pen/BjgKMR

html {
  background: pink;
}

body {
  background: yellow;
}

div {
  height: 1%;
}

inner {
  margin-bottom: 30px;
  margin-top: 20px;
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <p class="inner">block level element</p>
</div>
Run Code Online (Sandbox Code Playgroud)

div块的高度将计算为margin-bottom + content height of p element.我很困惑为什么height: 1%应该计算,auto因为父元素(htmlbody标签)没有明确设置其高度,但具有不同的高度,因为我们只是直接设置高度auto

如果我们直接将其设置为height: auto,则显然只需将高度设置为子块级元素的高度,该高度不包括其下边距.

html {
  background: pink;
}

body {
  background: yellow;
}

div {
  height: auto;
}

inner {
  margin-bottom: 30px;
  margin-top: 20px;
}
Run Code Online (Sandbox Code Playgroud)
<div><p class="inner">block level element</p></div>
Run Code Online (Sandbox Code Playgroud)

我已经阅读了CSS 2.1规范并考虑我的问题可能包含高度属性和边缘折叠主题,但仍然无法理解为什么它在Chrome ver中的行为不同.47.0.2526,虽然Firefox版本.44.0.2将显示具有相同值的高度.

列出的参考文献:https:
//www.w3.org/TR/CSS2/visudet.html#the-height-property

  • 10.5:百分比

    ...如果未明确指定包含块的高度(即,它取决于内容高度),并且此元素未绝对定位,则该值将计算为"auto"....

  • 10.6.3:overflow计算时正常流程中的块级非替换元素visible.

    ...如果'height'是'auto',则高度取决于元素是否具有任何块级子元素以及它是否具有填充或边框:

    元素的高度是从其顶部内容边缘到下面第一个适用的距离:

    1. 如果框使用一行或多行建立内联格式化上下文,则为最后一个行框的下边缘
    2. 如果孩子的下边距没有因元素的下边距而崩溃,则其最后一个流入子项的底部(可能是折叠)边缘的下边缘
    3. 最后一个流入子项的下边界边缘,其上边距不会随元素的下边距折叠
    4. 零,否则

https://www.w3.org/TR/2011/REC-CSS2-20110607/box.html#collapsing-margins

  • 8.3.1折叠边距.

    如果元素没有顶部边框,没有顶部填充,并且子节点没有间隙,则插入块元素的上边距将与其第一个流入块级子节点的上边距折叠.

    如果盒子没有底部填充,则"高度"为"auto"且"min-height"为零的流入块盒的底部边缘将与其最后一个流入块级子的底部边缘折叠底部边框和孩子的下边距不会因具有间隙的上边距而崩溃.

    ...如果框的顶部和底部边距相邻,则边距可能会通过它折叠.在这种情况下,元素的位置取决于其与边缘正在折叠的其他元素的关系.

    • 如果元素的边距与其父元素的上边距折叠,则框的上边框边缘定义为与父元素相同.
    • 否则,元素的父元素不会参与边距折叠,或者仅涉及父元素的下边距.元素顶部边框边缘的位置与元素具有非零底边框时的位置相同.

Mic*_*l_B 25

首先,您有W3C标准,这是浏览器制造商的一套指南.

然后你就拥有了浏览器制造商,他们可以自由地做任何他们想做的事情(由Internet Explorer的偏差历史证明).

特别是,对于CSS百分比高度,浏览器之间的行为存在明显差异.

你发布了一个例子.这是另一个:

Flexbox中的百分比高度:Chrome/Safari与Firefox/IE

使用flexbox时,Chrome和Safari会根据父级height属性的值解析弹性项目的百分比高度.Firefox和IE11/Edge优先考虑父级的弹性高度.

Webkit浏览器似乎遵循对规范的更传统的解释:

CSS height属性

百分比
指定百分比高度.百分比是根据生成的框的包含块的高度计算的.如果未明确指定包含块的高度且此元素未绝对定位,则该值将计算为"auto".

auto
高度取决于其他属性的值.

换句话说,对于在流入子项上工作的百分比高度,父项必须具有设置的高度.

这是对规范的传统解释:术语"高度"是指height财产的价值.我个人认为,这种语言含糊不清,可以解释,但height财产要求已成为主要的实施方式.在处理百分比值时,我从未见过min-heightmax-height在父母身上工作过.

然而,最近,Firefox和IE扩大了他们的解释,以接受弹性高度.

Firefox和IE的示例使用父级的弹性高度作为子级百分比高度的参考:

知道哪些浏览器符合规范有点困难,因为正如我之前提到的那样,规范语言似乎含糊不清并且易于解释.

随着定义的这一部分的最后一次更新是在1998年(CSS2),以及新的高度形式如flex高度的出现,更新似乎早就应该了.

我认为可以说,当涉及到百分比高度时,在规范定义获得更新之前,您可以预期浏览器之间的渲染差异.


替代方案

当希望子元素占据父元素的全高时,可以考虑以下两种方法.

  1. 申请display: flex父母.这会自动设置align-items: stretch,告诉孩子扩展父级的完整可用高度.

  2. 适用position: relative于父母和position: absolute; height: 100%; width: 100%孩子.使用绝对定位,百分比高度将在父级上没有指定高度的情况下工作.

  • 感谢您的回复,其他资源也让我觉得要么遵循规范,要么发生意外行为实际上取决于浏览器提供商,应该避免它. (3认同)