关于在移动端避免使用100vh的原因及解决方案

模板网 2021-02-01

1. 为什么避免使用100vh

CSS中的Viewport单元听起来很棒。如果你想将一个元素设置成全屏高度,你可以设置高度:100vh,这样你就有了一个完美的全屏元素,它会随着视口的改变而改变大小!遗憾的是,事实并非如此。100vh在不同的浏览器的实现方式上也有一点微妙的变化,这使得它几乎毫无用处。最好避免100vh,而是依赖javascript来设置高度,以获得完整的视口体验。

核心问题是移动浏览器(Chrome和Safari)有一个“帮助”功能,地址栏有时可见,有时隐藏,改变了视口的可见大小。这些浏览器没有将100vh的高度调整为视口高度变化时屏幕的可见部分,而是将100vh设置为隐藏地址栏的浏览器高度。结果是,当地址栏可见时,屏幕的底部部分将被切断,从而破坏了100vh的初衷。

如下所示:

关于在移动端避免使用100vh的原因及解决方案

 

当地址栏可见时,由于移动浏览器不正确地将100vh设置为屏幕高度而没有显示地址栏,因此屏幕底部被切断。在上图中,应该在屏幕底部的按钮被隐藏了。更糟糕的是,当用户第一次使用手机访问网站时,地址栏会显示在页面顶部,因此用户体验是很糟糕的。

2. 解决方案

2.1 使用window.innerHeight

解决这个问题的一种方法是依赖javascript而不是css。当页面加载时,将高度设置为window.innerHeight将正确地将高度设置为窗口的可见部分。如果地址栏是可见的,那么window.innerHeight是全屏的高度。如果地址栏是隐藏的,那么window.innerHeight将是屏幕可见部分的高度,正如您所期望的那样。

2.1.1 在vue项目中使用

${app}/src/app.vue

<script>
export default {
  name: 'App',
  mounted() {
    // First we get the viewport height and we multiple it by 1% to get a value for a vh unit
    let vh = window.innerHeight * 0.01
    // Then we set the value in the --vh custom property to the root of the document
    document.documentElement.style.setProperty('--vh', `${vh}px`)

    // We listen to the resize event
    window.addEventListener('resize', () => {
      // We execute the same script as before
      let vh = window.innerHeight * 0.01
      console.log(vh);
      document.documentElement.style.setProperty('--vh', `${vh}px`)
    })
  },
}
</script>

${app}/views/foo.vue

<style lang="scss" scoped>
.container {
  height: 100vh; /* Fallback for browsers that do not support Custom Properties */
  height: calc(var(--vh, 1vh) * 100 - 46px);
</style>

在之前设置为100vh,可以兼容某些不支持自定义属性的浏览器。

遗憾的是,仍然没有一种简单的方法可以让一个元素在不依赖javascript的情况下占据整个视口高度。height: 100vh是如此接近伟大,但考虑到它在移动设备上的局限性,最好避免它。

2.2 使用vh-check

github地址为: https://github.com/Hiswe/vh-check

用法:

npm install vh-check
import vhCheck from 'vh-check'
vhCheck()
main {
  height: 100vh;
  /* 兼容不支持 var 变量的浏览器 (<= IE11) */
  height: calc(100vh - var(--vh-offset, 0px));
  /* 修正后的 100vh */
}

原来和方案是一样的

相关文章

  1. 5大Node.js框架,谁才是Node.js最佳框架?

    首先,框架的目的是帮助你在从头开始构建web应用程序时克服一些常见的开发挑战。在为自己选择Node.js框架之前应考虑哪些事项?为了帮助你回答这个问题,今天,我将介绍5个最佳的Node.js框架。

  2. 前端性能监控及推荐几个开源的监控系统

    web项目性能很重要,开发迭代过程中难免会有所忽视,性能会伴随产品的迭代而有所衰减。特别在移动端,网络一直是一个很大的瓶颈,而页面却越来越大,功能越来越复杂。并没有简单的几条黄金规则就可以搞定性能优化工作,我们需要一套性能监控系统持续监控、评估、预警页面性能状况、发现瓶颈,指导优化工作的进行。

  3. 一文梳理JavaScript中的this

    this是JavaScript的一个关键字,但它时常蒙着面纱让人无法捉摸,许多对this不明就里的同学,常常会有这样的错误认知:

  4. 只要五分钟,带你学会策略模式

    大家好,今天给大家介绍一个新的设计模式——策略模式。

  5. 使用V8和node轻松profile分析nodejs应用程序

    我们使用nodejs写好了程序之后,要是想对该程序进行性能分析的话,就需要用到profile工具了。

随机推荐

  1. 5大Node.js框架,谁才是Node.js最佳框架?

    首先,框架的目的是帮助你在从头开始构建web应用程序时克服一些常见的开发挑战。在为自己选择Node.js框架之前应考虑哪些事项?为了帮助你回答这个问题,今天,我将介绍5个最佳的Node.js框架。

  2. 前端性能监控及推荐几个开源的监控系统

    web项目性能很重要,开发迭代过程中难免会有所忽视,性能会伴随产品的迭代而有所衰减。特别在移动端,网络一直是一个很大的瓶颈,而页面却越来越大,功能越来越复杂。并没有简单的几条黄金规则就可以搞定性能优化工作,我们需要一套性能监控系统持续监控、评估、预警页面性能状况、发现瓶颈,指导优化工作的进行。

  3. 一文梳理JavaScript中的this

    this是JavaScript的一个关键字,但它时常蒙着面纱让人无法捉摸,许多对this不明就里的同学,常常会有这样的错误认知:

  4. 只要五分钟,带你学会策略模式

    大家好,今天给大家介绍一个新的设计模式——策略模式。

  5. 使用V8和node轻松profile分析nodejs应用程序

    我们使用nodejs写好了程序之后,要是想对该程序进行性能分析的话,就需要用到profile工具了。