很多情况下,开发设置了height:100%,最后效果都不是事先设想的那样。这一切都是因为height本身就是trick满满,再加上百分比这个buff就容易出现多种情况
我们设置百分比percent,最终计算后的height肯定是 基准 * percent。那重点就是这个基准到底是多少呢?接下来我们用code的形式来讨论一下。
非DOCTYPE声明
<!DOCTYPE html>声明表明是HTML5文档规范。这里把它单独拎出来是因为,如果不声明这个,那么百分比就会以最近的祖先节点设置的height为基准。
这不是我们讨论的重点
给出一个code,有兴趣的自行调整test
<html>
<body>
<div style="height:50%;">
<div>
<div style="height:50%;">
我还是有1/4高的
</div>
</div>
</div>
</body>
</html>
block
接下来讨论block元素
position:static(默认)|relative|sticky
父元素没有显式设置height
若父元素没有显示的设置height样式,那么该元素设置的height百分比无效
<!DOCTYPE html>
<html>
<body>
<div>
<div style="height:50%;background-color:#92cbe6;">
虽然我想100%,但实际只有文字高
</div>
</div>
</body>
</html>
注意这里一定要是父元素设置了height,,祖先元素设置了也是无效的
<!DOCTYPE html>
<html>
<body>
<div style="height:100%;background-color:#999999;">
<div>
<div style="height:50%;background-color:#92cbe6;">
虽然我想100%,但实际只有文字高
</div>
</div>
</div>
</body>
</html>
对于html标签,它则没有这个要求,它的基准就是屏幕高度,也就是window.innerHeight
<!DOCTYPE html>
<html style="height:100%;background-color:#999999;">
<body>
<div >
<div>
<div style="height:50%;background-color:#92cbe6;">
虽然我想100%,但实际只有文字高
</div>
</div>
</div>
</body>
</html>
父元素显式设置height
这时候子元素的基准 = 父元素的实际content高度
实际是什么意思
- height无效设置
有时候,父元素也设置了height,例如height:100%,但这时候对于子元素来说,基准还是NaN,因为父元素自己在计算height:100%,由于它的父元素没有设置height,这就导致父元素的height:100%是失效的。这时候就变成了上一个没有显示设置height的场景
<!DOCTYPE html>
<html>
<body>
<div style="height:100%;">
<div style="height:100%;background-color:#92cbe6;">
虽然我想100%,但实际只有文字高
</div>
</div>
</body>
</html>
下面这种只设置了min-height情况,其实父元素也是无效设置
<!DOCTYPE html>
<html>
<body>
<div style="min-height:100px;border: solid 1px rgb(250,0,255)">
<div style="height:100%;">
虽然我想100%,但实际只有文字高
</div>
</div>
</body>
</html>
- height实际值不为设置的值
别忘了,我们还有min-height/max-height这些,它们也会影响最终的height。在下面这种情况,基准其实是60px
<!DOCTYPE html>
<html>
<body>
<div style="height:50px;min-height:60px;">
<div style="height:100%;background-color:#92cbe6;">
content: 60px
</div>
</div>
</body>
</html>
content高度:根据盒子模型,父元素的有padding、content、border、margin这些。我们需要知道的是,子元素的百分比基准是以父元素的content高度为准的。为什么强调这个,是因为有别的情况不是这样
<!DOCTYPE html>
<html>
<body>
<div style="height:50px;min-height:60px;padding:10px;border:5px solid black;margin:10px">
<div style="height:100%;background-color:#92cbe6;">
content: 60px
</div>
</div>
</body>
</html>
- 多个祖先节点百分比设置
这里本质上还是上面说的那个原则,看父节点是否设置了有效height。简单描述成,如果某节点A设置了非百分比height,那么它下面节点B设置的百分比height会生效,因为A有基准。B下面C设置的百分比也会生效,因为B生效后也有了基准。但是,如果C下面的D没有设置height,那D下面的E设置的百分比就不会生效,因为中间断了
<!DOCTYPE html>
<html>
<body>
<div style="height:100px;">
<div style="height:100%;">
<div style="height:100%;">
<div>
<div style="height:100%;background-color:#92cbe6;">
我失效咯
</div>
</div>
</div>
</div>
</div>
</body>
</html>
- 如果一个元素设置绝对高度且为绝对定位,那子元素的百分比基准是多少?
<!DOCTYPE html>
<html>
<body>
<div style="height:200px;">
<div style="height:100px;position:absolute;">
<div style="height:100%;">
我到底是100px还是200px呢?
</div>
</div>
</div>
</body>
</html>
答案是100px哦。
对于普通定位的元素来说,它只关注父元素的实际高度,而不用关注父元素是什么定位。
position:absolute
它大致逻辑与上面一致,不一样的是这个基准值。它找到的基准不是父元素的基准。它要找的,是离它最近的、具有定位(position 属性值为 relative, absolute, fixed, 或者 sticky)的祖先元素
祖先元素存在
这又分为了以下几种情况
- 祖先元素设置了有效height
- 祖先元素设置了无效height但被撑起
- 祖先元素设置了无效height且没被撑起
- 祖先元素未设置height但被撑起
- 祖先元素未设置height且没被撑起
- 祖先元素设置了有效height
当祖先元素设置了有效height,那么基准 = 该祖先节点"设置的"content高度 + padding高度
注意未包含border
<!DOCTYPE html>
<html>
<body>
<div style="height:100px;">
<!-- 下面的height:50%是有效的,因为父元素显示设置了height:100px -->
<!-- 最后采用的是由这个设置的50%而转换成的实际高度,而不是下面80px撑起的高度 -->
<div style="height:50%;position:relative;border:10px solid black;padding:10px">
<div style="height:80px;">
<div>
<div style="height:100%;position:absolute;background-color:#92cbe6;">
content: 100*0.5+10+10 = 70 px
</div>
</div>
</div>
</div>
</div>
</body>
</html>
- 祖先元素设置了无效height但被撑起 当祖先元素设置了无效height,且被子元素高度撑起来了,那么基准 = 该祖先节点的"实际撑起的"content高度 + padding高度
<!DOCTYPE html>
<html>
<body>
<!-- 下面的height:50%是无效的 -->
<!-- 最后采用的是由子元素撑起来的80px -->
<div style="height:50%;position:relative;padding:10px">
<div style="height:80px;">
<div style="height:100%;position:absolute;background-color:#92cbe6;">
content: 80+10+10 = 100 px
</div>
</div>
</div>
</body>
</html>
- 祖先元素设置了无效height且没被撑起 此时基准 = 该祖先节点的padding高度
<!DOCTYPE html>
<html>
<body>
<!-- 下面的height:50%是无效的 -->
<!-- 最后absolute元素height为0 -->
<div style="height:50%;padding:10px;position:relative">
<div style="height:100%;position:absolute;background-color:#92cbe6;">
content:20px
</div>
</div>
</body>
</html>
- 祖先元素没有设置height但被撑起 此时基准 = 该祖先节点的"实际撑起的"content高度 + padding高度
<!DOCTYPE html>
<html>
<body>
<div style="position:relative">
<div style="height:80px;">
<div style="height:100%;position:absolute;background-color:#92cbe6;">
content: 80px
</div>
</div>
</div>
</body>
</html>
- 祖先元素没有设置height且没被撑起 此时基准 = 该祖先节点的padding高度
<!DOCTYPE html>
<html>
<body>
<div style="position:relative">
<div style="height:100%;position:absolute;background-color:#92cbe6;">
content: 0
</div>
</div>
</div>
</body>
</html>
祖先元素不存在
当不存在这样一个祖先元素时,这个基准值就是屏幕高度
<!DOCTYPE html>
<html>
<body>
<div style="height:100px;">
<div style="height:100%;position:absolute;background-color:#92cbe6;">
content:撑满
</div>
</div>
</body>
</html>
position:fixed
基准就是屏幕高度,window.innerHeight
<!DOCTYPE html>
<html>
<body>
<div style="height:100px;">
<div style="height:50%;position:relative;border:10px solid black;padding:10px">
<div style="height:80px;">
<div>
<div style="height:100%;position:fixed;background-color:#92cbe6;">
content = window.innerHeight
</div>
</div>
</div>
</div>
</div>
</body>
</html>
inline-block
我其实感觉和block是一样的。但具体的code没验证,有兴趣的可以自己写写