做移动端响应式布局,比较常见的vw, vh,通过这两个视口单位,就可以实现响应式了。然后官方后续又继续推出了vmin,vmax, dvw, dvh,dvmax等一系列单位。既然推出新的单位,那一定是为了解决旧方案存在的不足或者问题。
1. 问题和案例
vw(viewport width): 视口宽度, 1vw = 视口宽度的1%vh(viewport height): 视口高度,1vh = 视口高的1%rem: 根节点fontSize大小为一个最小单位
1. vw
1.1 局限
移动端响应适配方案,我们可以根据设计稿通过postcss的将px转成vw或者rem来实现响应式布局。比如375的的设计稿,那么10px就会转成100 / 375 * 10约等于2.666vw,转成vw之后,页面内容就能根据用户具体屏幕宽度来做响应式,屏幕越宽,1vw的实际长度越长,内容也越大。rem本质也是通过具体屏幕宽度,动态改变根元素fontSize大小来实现响应式。
下面根据375作为基准尺寸画一个容器转vw。
效果展示。
诶,看着效果挺不错,没什么问题,但是用户横屏查看或者用平板查看的时候,问题就出现了。
在横屏情况下,长宽比反过来了。但是我们还是以vw进行响应式布局,这时候实际上物理尺寸并没有发生改变,而元素占屏幕的比例变得非常大,所以也会严重脱离UI预期。
这种情况有什么办法解决吗?有的,兄弟有的。这时候vmin就可以出场了。
1.2 vmin新方案
vmin: 视口较小尺寸的 1%(如果屏幕宽度大于屏幕高度,那么1vmin就是高度的1%, 反之则为屏幕宽度1%)
vmax: 视口较大尺寸的 1%(如果屏幕高度大于屏幕宽度,那么1vmin就是宽度的1%, 反之则为屏幕高的1%)
我们将将vw替换成vmin,来看一下效果。
先看一下竖屏响应式。
没问题,在验证下横屏和平板。
完美,这时候在横屏或者情况下平板情况下,元素就不会脱离预期的UI(UI稿中元素占整个容器的比例),完美解决。
1.3 总结
vmin可以很好的解决vw做响应式在横屏和平板设备下出现的元素尺寸或者字体过大的问题。
2 vh
2.1局限
如何画一个满屏的容器,我第一反应是height: 100vh, width: 100vw;,pc上开发没有任何问题。
但是再真机上一跑,问题立马就出现了,原因是100vh是按照浏览器视口高度,而手机浏览器视口内,除了页面,还有导航栏等信息,那么这时候我们的页面实际上是小于100vh的,所以就出现的需要滚动的情况。
那这种方案在移动端就有问题了,有没有什么办法解决呢? 我们可以通过fixed定位来画一个满屏的容器,但是有的场景不能用定位呢,还有什么办法吗?有的兄弟,还有的。
2.2 dvh方案
这里补充一个概念,css里面的vh参考的是布局视口(layout viewport),而移动端用户看到的是可见视口(visual viewport),而两者在有导航栏等信息的时候是会有差异的。
然后给基于上述类似的俄问题,浏览器推出了几个新的视口单位。
lv*: 大视口(最大可能高度)sv*小视口(刨除导航栏等信息以外可见视口,最小可能高度)dv*动态视口(动态视口)
而动态视口,顾名思义,视口高度是动态变化的,正是我们目前需要的,
下面介绍一个新的单位dvh(dynamic vh),实时随 UI 变化,地址栏收起/展开时会动态改变,完美的替代方案。接下来看下效果。
2.3 总结
dvh会根据实际ui页面的高度来动态变化从而避免移动端浏览器地址栏等组件占据视口导致出现滚动条的情况。
视口单位都哪些?
| 单位 | 等效于 |
|---|---|
lvw、lvh、lvi、lvb、lvmin、lvmax | 大型视口单位,相对于隐藏所有可选浏览器界面元素的视口可见空间。等于非变体视口相对单位。只要视口大小不变,就不会发生变化。 |
svw、svh、svi、svb、svmin、svmax | 小型视口单位,相对于视口的可见空间,其中显示所有可选的浏览器界面元素。只要视口大小不变,就不会发生变化。 |
dvw、dvh、dvi、dvb、dvmin、dvmax | 相对于视口的当前可见空间的动态视口单元。浏览器界面元素显示或隐藏时的变化。 |