导火索
如上图,有一个fixed的蒙层,高度设置了100vh,白色块内容6行bottom: 0,底部页面的高度不超过当前视口高度(页面不能上下滑动),可以看到白色块被吞了一部分。而当蒙层高度设置100%时,可以完整显示出来。通过搜索发现源自以下问题:
- 在地址栏可以隐藏时,vh和100%的高度并不一致
- fixed是相对于当前视口的定位,高度超出当前视口时会显示不出来
对于非fixed定位
存在一个初始包含块(ICB)的静态初始视口,它的大小是最小可能的,也就是说当顶部地址栏、底部标签栏显示时的视口的大小,可以使用html.clienHeight
获得。
另外,vh、vw也是静态的,它的大小是最大可能的,即顶部地址栏、底部标签栏显示时的视口的大小。
当前视口可以使用window.innerHeight
获得。
Chrome
- 当内容高度 ≤ ICB时,页面是不能上下滑动的。这时如果fixed蒙层的高度比ICB大(比如设置为100vh),底部就会被吞掉一部分。
- 当ICB ≤ 内容高度 < ICB + B/2时,这时页面能滑动,松开手指后会恢复。同样存在上述问题。不过快速滑动时,能扩张到100vh,当松开手指且地址栏隐藏时,触发resize事件改变window.innerHeight,多出的部分bgc和document一致(html和body中的前一个bgc作用在document上)。
- 当ICB + B/2 ≤ 内容高度 < ICB + B时,这时页面能滑动,松开手指会扩张到100vh,和上述一样
- ICB + B ≤ 内容高度时,同上
Firfox
不同于Chrome,Firefox无论内容高度多少,都可以上下滚动,当地址栏显示或隐藏时,触发resize事件改变window.innerHeight,多出的部分bgc为白色。
Safari
待补充
对于fixed定位
fixed定位的元素大小、位置与window.innerHeight看齐。首先跟随滑动,当window.innerHeight变更后,会重新调整元素的大小、位置。
大小
- %:向window.innerHeight看齐
- vh:固定值
- top + bottom + left + right:向window.innerHeight看齐
位置
- %:向window.innerHeight看齐
- vh:固定值
- px: 固定值
全屏或地址栏始终显示的
100vh = 100% ICB
总结
- 对于fixed蒙层最大不要超过vh、vw,不然会超出看不见。
- 页面内容不够滑动时,fixed蒙层使用100%。
- 页面内容能滑动时,fixed蒙层使用100%或100vh都可以。