原文连接:Some Things You Oughta Know When Working with Viewport Units,by Chris Coyierjavascript
David Chanin 写了一篇 简短的文章 总结了在手机端为元素设置 height: 100vh
带来的一个问题。css
能够总结为下图:html
_100vh_
高的元素的底部。带来的问题是,Chrome 浏览器没有把地址栏考虑在内,致使地址栏显示时,迫使底部元素超出视口以外了。
<div class="full-page-element">
<button>Button</button>
</div>
复制代码
.full-page-element {
height: 100vh;
position: relative;
}
.full-page-element button {
position: absolute;
bottom: 10px;
left: 10px;
}
复制代码
假设 .full-page-element
是页面里的第一个元素,页面也没发生滚动。咱们指望的是看见这个按钮是在可视区域的底部、沿着 100vh
元素的底部边缘显示的。可是因为地址栏的显示,致使这个元素超出视口以外看不见了,在 iOS Safair 和 Android Chrome 中都能看到这个效果。java
我常常会使用下段代码:git
body {
height: 100vh; /* 不用考虑父元素高度,直接设置就能生效 */
margin: 0;
}
复制代码
这是一个快速的、在不涉及任何其余元素的状况下,设置 body
为全高(full height)的方式。我一般会在低风险的演示 demo 上这么作,可是这仍是有问题的,由于随着浏览器地址栏的出现和消失,页面可能会发生跳动,或者说页面可能不会像我想象中的那样展现。github
你可能想到使用 body { height: 100% }
来解决问题,但这也有一个 问题。body
是 <html>
的子元素,而 <html>
的高度默认是由内容撑开的。web
若是你须要设置 body
为全高,也须要同时设置 <html>
才行:浏览器
html, body {
height: 100%;
}
复制代码
……这并非什么大不了的事情,它具备可靠的跨浏览器一致性。app
💡 译注:post
这是做者要讲的 第一个问题——
100vh
没有将手机端的地址栏计算在内,致使地址栏出现时,相对于 100vh 元素定位在底部的元素会由于地址栏的出现,被推出到视口以外。这个问题的解决办法是改用
html, body { height: 100%; }
声明解决。
能看出来,底部边缘的定位是很复杂的。再来看看上面 button
元素的定位代码:
.full-page-element button {
position: absolute;
bottom: 10px;
left: 10px;
}
复制代码
button
元素是 position: absolute
定位的,当由于父元素 .full-page-element
100vh
的设置出现问题时,那么相对于它进行底部定位的按钮天然也会有问题。
若是咱们有在屏幕底部定位元素的需求(好比说一个固定导航),你们可能会使用 position: fixed; bottom: 0;
来解决,这看起来 没什么问题,浏览器也会按照咱们预期的工做。
💡 译注:
这是做者要讲的 第二个问题—— 屏幕底部的固定定位,应该使用
position: fixed
来实现,而不是position: absolute
定位。
水平视口单元一样是怪异、有问题的,Windows 系统里的页面 滚动条 一般会占用可视空间,而 100vw
的计算是没有把滚动条计算在内的。换句话说,100vw
会以一种你意想不到的方式致使水平滚动。
也就是说,视口单位(Viewport Units)并不能反映是的视口尺寸(viewport's size)。
若是页面存在水平滚动条,那么下面的代码就会致使水平滚动:
.wrapper {
width: 100vw; /* 这样会有问题 */
}
复制代码
为了排除滚动条带来的影响,减去它的宽度就能够了。
.wrapper {
width: calc(100vw - var(--scrollbar-width)); /* 这样就没有问题了 */
}
复制代码
💡 译注:
这是做者要讲的 第三个问题—— Windows 系统中的滚动条是占据空间的,这个会致使 width: 100vw 的设置带来问题,若是还坚持使用此方式的话,不要忘记减去滚动条的宽度。
这个方式的具体讲解,请参考《100vw 下滚动条引起的问题》这篇文章。
(完)