Chrome和Firefox中的高度呈现方式不同

时间:2016-02-21 06:21:07

标签: html css css3 flexbox language-lawyer

我发现如果我们使用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;
}

<div>
  <p class="inner">block level element</p>
</div>
&#13;
&#13;
&#13;

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

如果我们直接将其设置为height: auto,则显然只会将高度设置为子块级元素的高度,而不包括其底部边距。

&#13;
&#13;
html {
  background: pink;
}

body {
  background: yellow;
}

div {
  height: auto;
}

inner {
  margin-bottom: 30px;
  margin-top: 20px;
}
&#13;
<div><p class="inner">block level element</p></div>
&#13;
&#13;
&#13;

我已阅读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:百分比

      

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

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

      

    ...如果&#39;身高&#39;是&#39; auto&#39;,高度取决于元素是否具有任何块级子元素以及它是否具有填充或边框:

         

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

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

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

  • 8.3.1折叠边距。

      

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

         

    具有高度&#39;的流入块箱的底部边缘。 &#39; auto&#39;和一个最小高度的&#39;如果盒子没有底部填充且没有底部边框且孩子的底部边缘没有在具有间隙的顶部边缘处折叠,则零折叠与其最后一个流动块级子的底部边缘。

         

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

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

1 个答案:

答案 0 :(得分:21)

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

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

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

您已发布了一个示例。这是另一个:

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

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

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

  

CSS height property

     

百分比
指定百分比高度。百分比是根据生成的包含块的高度计算的。如果未明确指定包含块的高度且该元素未完全定位,则该值计算为&#34; auto&#34;。

     

自动
高度取决于其他属性的值。

换句话说,对于在流动儿童中工作的百分比高度,父母必须具有设定的身高。

这是对规范的传统解释:术语&#34;身高&#34;表示height属性的值。我自己的观点是,这种语言含糊不清,可以解释,但height属性要求已成为主要的实现。在处理百分比值时,我从未见过min-heightmax-height在父母身上工作。

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

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

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

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

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

替代解决方案

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

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

  2. 在父亲身上申请position: relative,在孩子身上申请position: absolute; height: 100%; width: 100%。使用绝对定位时,百分比高度将在父级上没有指定高度的情况下工作。