目录
第 4 步:在您的 CSS 中使用 height: 100vh 或者 min-height: 100vh 。
前言
在移动端中,我们通常想要某块页面全屏展示而使用height:100vh来实现,但是不同的浏览器在地址栏/工具栏的影响下,实现方式也有区别,使得其无法很好的适配多种浏览器。所以最好避免通过css来设置高度,而是通过js来设置高度,获得完整的视口体验!
产生问题的原因:
移动浏览器(Chrome和Safari)具有“帮助”功能,其中地址栏有时可见,有时隐藏,从而改变了视口的可见大小。 这些浏览器没有将100vh
高度调整为视口高度变化时屏幕的可见部分,而是将100vh
设置为浏览器的高度,并隐藏了地址栏。 结果是,当地址栏可见时,屏幕的底部将被切除。
如下图:在地址栏出现/显示的时候,浏览器错误的将100vh设置为屏幕高度,而不是除去地址栏的可见宽度,因此下部分的蓝色按钮被挡住看不见。
解决方法:(js)
window.innerHeight
解决此问题的一种方法是依靠javascript而不是CSS。 页面加载时,将高度设置为window.innerHeight
可以将高度正确设置为窗口的可见部分。 如果地址栏可见,则window.innerHeight
将为屏幕上可见部分的高度。 如果地址栏是隐藏的,则window.innerHeight
将是全屏的高度,这正是您所期望的。
诀窍是将视口值存储在CSS变量中,并将其应用于元素而不是 vh
单位。
在vue项目中实现
${app}/src/app.vue
<script>
export default {
name: 'App',
mounted() {
//首先我们获得视口高度并将其乘以1%以获得1vh单位的值
let vh = window.innerHeight * 0.01
// 然后,我们将——vh自定义属性中的值设置为文档的根
document.documentElement.style.setProperty('--vh', `${vh}px`)
// 我们监听resize事件 视图大小发生变化就重新计算1vh的值
window.addEventListener('resize', () => {
// 我们执行与前面相同的脚本
let vh = window.innerHeight * 0.01
console.log(vh);
document.documentElement.style.setProperty('--vh', `${vh}px`)
})
},
}
</script>
${app}/views/foo.vue
因此,我们现在可以像使用任何其他单位一样使用 --vh
vh
我们的高度值,将其乘以 100,我们就得到了我们想要的完整高度。
<style lang="scss" scoped>
.container {
height: 100vh; /* 对于不支持自定义属性的浏览器的回退 */
height: calc(var(--vh, 1vh) * 100);
</style>
更简单的方式(纯css)
看到了一片推文,解决了只可以通过js来实现适应屏幕视图的问题,使用的是纯css
在他的例子中希望写一个基本的弹性框布局(页眉、主页脚、粘性页脚),像是下面这样
实现代码:
//html部分
<body>
<header>HEADER GOES HERE</header>
<main>MAIN GOES HERE</main>
<footer>FOOTER GOES HERE</footer>
</body>
//css部分
<style>
body {
display: flex;
flex-direction: column;
margin: 0;
min-height: 100vh;
}
main {
flex: 1;
}
</style>
但是在iphone上运行览器测试,他的粘性页脚看起来并不那么粘:
页脚隐藏在 Safari 的菜单栏下方
使用-webkit-fill-available 可以允许元素本质上适合特定的布局,即填充该属性的可用空间。
添加以下样式
<style>
body {
min-height: 100vh;
/* 移动端视图bug修复 */
min-height: -webkit-fill-available;
}
html {
height: -webkit-fill-available;
}
</style>
这样就可以实现上图的粘性底部了,但是这个仍然有一些问题,在某些情况下只 -webkit-fill-available
会导致Chrome出现问题
Chrome出现问题(纯css)
在最后一篇博文中给出了修复方案,安装插件PostCSS来修复iOS的错误 100vh
。
它可以在Chrome(在某些情况下只 -webkit-fill-available
会导致Chrome出现问题),iOS / iPad / MacOS Safari和所有其他浏览器。纯CSS解决方案,不需要JS。
<style>
body {
/* 由于底部面板,页脚将在iOS Safari上隐藏 */
height: 100vh;
}
</style>
添加支持
<style>
body {
height: 100vh;
}
/* 避免Chrome浏览器看到Safari黑客 */
@supports (-webkit-touch-callout: none) {
body {
/* The hack for Safari */
height: -webkit-fill-available;
}
}
</style>
它也适用于 min-height
、 max-height
Usage 用法
第 1 步:安装插件:
npm install --save-dev postcss postcss-100vh-fix
第 2 步:检查您的项目是否存在 PostCSS 配置:
postcss.config.js
在项目根目录中、 "postcss"
部分 package.json
或 postcss
捆绑包配置中。
如果您不使用 PostCSS,请根据官方文档 official docs 添加,并在设置中设置此插件。
第 3 步:将插件添加到插件列表:
module.exports = {
plugins: [
+ require('postcss-100vh-fix'),
require('autoprefixer')
]
}
第 4 步:在您的 CSS 中使用 height: 100vh
或者 min-height: 100vh
。
参考或翻译
避免在移动网络上使用100vh https://chanind.github.io/javascript/2019/09/28/avoid-100vh-on-mobile-web.html
在移动设备上观察单位的技巧
https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
新的通过css解决vh
CSS fix for 100vh in mobile WebKit - Matt Smith
改进了上面博客的方法以修复 Chrome 中的错误并包装到 PostCSS 插件中(这样您就可以编写 min-height: 100vh
代码并且不记得进行黑客攻击)。
GitHub - postcss/postcss-100vh-fix: PostCSS plugin to fix height/min-height: 100vh on iOS