今天写一个页面时,发现一个有趣的事情,我试图让一个遮罩层高度为100%,结果一直不生效,情况如下:

<body style="height: 100%;">
  <div style="min-height: 100%;">
    <div style="height: 100% width:100%;"></div>
  </div>
</body>

如上方示例代码,外部是主容器,内部是一个遮罩层。

  1. 父层设置了百分比min-height,同时没有设置height
  2. 子层height设置为100%

按照思路,子层应该和父层拥有一样的高度,然而浏览器渲染结果并不是这样。查了下CSS规范文档(CSS 2.1 Specification)发现了问题所在,于是做一些记录。

CSS 2.1 规范

CSS 2.1 规范关于百分比高度的说明:

The percentage is calculated with respect to the height of the generated box’s containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to ‘auto’.

规范里所说的the containing block就是本次示例中的父层,正如加粗部分所说,示例中父层确实没有被指定明确的高度(explicitly height),但是它有指定min-height值,于是它的高度取决于它的子内容的高度。

而文档中关于最小高度的规范原文如下:

Specifies a percentage for determining the used value. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the percentage value is treated as '0' (for 'min-height') or 'none' (for 'max-height').

由于一路往上层高度都是100%,所以高度理论上应该是如文中加粗部分所描述的一路继承下来。

浏览器表现

我试过的所有浏览器都将子元素高度设置为它的内容的高度,而忽略了子元素的100%高度设置。不知所措一波操作之后发现,如果我给父层设置一个任何数值的高度之后,子元素的高度居然正常了。

所以,当百分比高度的父元素被设置了高度,就算是0,百分比高度的子元素也会被计算。

然而,进一步测试,又发现了问题。当父层的实际高度超出了它的min-height时,子层的高度并没有跟着增加。此时仿佛子层的height数值被设置成了父层的min-height,所以当有滚动的时候,子层会不足以撑满整个父层大小。于是,碰到这个问题的时候,如果你的父层会出现滚动,还是不能简单的设置高度为0来解决。