如何正确编写一个占满全部可视区域的组件(hero component)?
什么是 hero component
hero component 或者 hero image 是一个网页设计术语,用于描述欢迎访问者访问网页的全屏视频、照片、插图或横幅。该图像始终位于网页顶部附近的显着位置,通常会在屏幕上延伸整个宽度。
我们经常见到这种 hero component,在视觉上占据了整个视口的宽度和高度。比如特斯拉的官网:
如何实现一个 hreo component?
很多人可能会不假思索的写出下面的 css 代码:
.hero {
width: 100vw;
height: 100vh;
}
你写完了这样的代码,满意地提测后。测试同学走过来告诉你:你的代码在苹果手机上不好使了!
如图所示,hreo component 被搜索栏挡住了。
又是 safari 的问题!我们可以先停止关于 Is Safari the new Internet Explorer? 的辩论,看看问题的成因和解决办法。
什么是视口单位
vh
单位最初存在时被定义为:等于初始包含块高度的 1%。
vw
= 视口尺寸宽度的 1%。vh
= 视口大小高度的 1%。
将元素的宽度设置为 100vw
,高度设置为 100vh
,它就会完全覆盖视口。这就是上面 hero component 实现的基本原理:
这看起来非常完美,但在移动设备上。苹果手机的工程师觉得我们应该最大化利用手机浏览器的空间,于是在 Safari 上引入了动态工具栏,动态工具栏会随着用户的滑动而收起。
页面会表现为:高度为 100vh
的元素将从视口中溢出。
当页面向下滚动时,动态工具栏会收起。在这种状态下,高度设为 100vh
的元素将覆盖整个视口。
图片来自于:大型、小型和动态视口单元
svh / lvh / dvh
为了解决上面提到的问题,2019 年,一个新的 CSS 提案诞生了。
- svh(Small Viewport Units):为视口较小尺寸的高度的 1%。
- lvh(Large Viewport Units):为视口大尺寸的高度的 1%。
- dvh(Dynamic Viewport Units):为动态视口的高度的 1%。
上面的解释来自于 MDN,读起来有点拗口,其实顾名思义,再结合下面的动图就很好理解:
在 tailwindcss 的文档中,对 dvh 有一个漂亮的动画演示:tailwindcss.com/blog/tailwi…
用以上的属性可以完美解决上面的 safari 中视口大小的问题,值得一提的是,有的人会建议始终使用 dvh
代替 vh
。从上面的动图可以看到,dvh
在手机上其实会有个延迟和跳跃。所以是否使用dvh
还是看业务的实际场景,就我而言,上面的 hero component 的例子使用 lvh
更合适。
兼容性
你可以在 can I use 中查看兼容性:
可以看到,这三个 css 属性还算是比较新的特性,如果为了兼容旧浏览器,最好是把 vh
也加上:
.hero {
width: 100vw;
height: 100vh;
height: 100dvh;
}
这样,即使在不支持新特性的浏览器中,也会降级到 vh
的效果。
感谢阅读本文~
来源:juejin.cn/post/7352079427863592971