【问题标题】:100vh height when address bar is shown - Chrome Mobile显示地址栏时的 100vh 高度 - Chrome Mobile
【发布时间】:2019-03-21 18:39:33
【问题描述】:

我遇到过几次这个问题,想知道是否有解决这个问题的方法。 我的问题出现在 Chrome 移动应用程序上。在那里,您可以向下滚动一点,地址栏就会消失。到目前为止,一切都很好,让我们举个例子:
容器的height 设置为100vh

如您所见,底部被切断了。

当我向下滚动时,它看起来像这样:

现在看起来不错。所以很明显,Chrome 将地址栏的高度计算为视口高度。所以我的问题是:

有没有一种方法,不管有没有地址栏,它看起来都一样?让容器膨胀还是什么?

【问题讨论】:

  • 只有脚本解决方案才能解决这个问题。在这里阅读:stackoverflow.com/questions/37112218/…
  • 没有代码很难帮你..
  • 为什么不使用 height:100% 而不是 100vh? Chrome 应用返回的值包括高度为 100vh 的地址栏。
  • @AndrewLi 如您所见,有一个列表。使用 100% 时,容器不会是全高。我必须在车身高度上设置 100vh 才能使其正常工作,这导致了同样的问题。
  • 我有同样的问题,但是将高度设置为 100% 并不能解决问题。

标签: html css google-chrome address-bar mobile-chrome


【解决方案1】:

根据这个official article on Chrome web,设置高度以填充可见视口的正确方法是使用height: 100%,在<html> 元素或position: fixed 元素上。如文档所述,这确保了与移动 Safari 的兼容性,并且与 URL 栏的大小无关。

【讨论】:

  • 非常感谢。这篇文章实际上帮助我了解了幕后发生的事情。所以对于我的用例来说,100% 似乎是正确的,因为无论如何它都是一个 position: fixed 元素。
  • 重要的是要注意,如果您仍然希望能够促进地址栏可见性的滚动切换,<html> 的高度仍应设置为 100vh(或大于100%),并且只有目标填充元素应该被分配position: fixed; height: 100%
  • 我也有同样的问题,但是将高度设置为 100% 并不能解决问题。
  • 唯一一个真正适合我的答案。谢谢。
【解决方案2】:

尝试使用min-height: -webkit-fill-available。您也可以在height: 100vh 下方添加它作为后备。

【讨论】:

  • 我花了好几年才找到这个!
  • 由于我必须在内部使用带有滚动容器的 100vh,我实际上在 max-height 的不同用例中使用了这个专有的 webkit 变量。
【解决方案3】:

您可以通过在 html 和 body 标签上设置 height: 100% 来解决地址栏问题 并且将主体的边距和填充设置为零 您还可以在主 div 中处理滚动以获得更好的控制

【讨论】:

  • 您可以添加box-sizing: border-box;,而不是将边距/填充设置为零
  • 非常感谢。添加高度:100% 固定在身体上。
【解决方案4】:

社区仍然没有严格的协议,从开发人员的角度来看,浏览器应该如何处理顶部、底部和侧面板的移动。

问题中提到的问题众所周知:

  1. 这一切都始于Apple Webkit Issue。问题之一是网站开发人员使用vh 来计算字体大小(calc(100 / vh * something))。如果 100vh 是动态的,当用户向下滚动并且地址栏被隐藏时,字体大小和任何其他绑定元素一样,都会被扭曲,从而产生非常糟糕的用户体验,更不用说是 CPU/GPU 密集型任务了。
    Apple 的决定是将较大的屏幕尺寸(没有地址栏)不断匹配到 100vh。因此,当显示地址栏并且您使用100vh 高度时,底部将超出屏幕。 许多开发人员不同意该决定,并认为视口单元是动态的,并且完全等于可见的“视口”。

  2. Google Chrome 团队决定成为 compatible with the Apple browser 并坚持同样的决定。

  3. height: 100% 在大多数现代浏览器中等于真正的可见部分,即高度会有所不同,具体取决于地址栏在滚动期间是可见还是隐藏。

  4. 栏不仅可以出现在屏幕的顶部,还可以出现在底部(现代 iOS),以及屏幕键盘可以使视图更短。 有一个nice demo可以在移动设备中检查100vh vs 100%的实际大小。


解决方案 1

html, body { height: 100%; }
.footer-element { 
  position: fixed; 
  bottom: 10px;
}

解决方案 2
补偿对vh 的一些依赖性,可见条的高度等于“100vh - 100%”,当条被隐藏时,差异将为 0。

html, body { height: 100vh; }
.footer-element { 
  position: fixed; 
  bottom: calc(10px + (100vh - 100%));
}

【讨论】:

    【解决方案5】:

    我刚刚想出了一种方法来调整元素的大小,以便高度不包括带有屏幕导航栏和浏览器顶栏的 android 无主页按钮智能手机。如果内容大于屏幕,则元素应该增长到可以容纳所有内容的大小,这就是我使用 min-height 的原因。


    编辑:

    使用类添加了一个 sn-p,而不是更改 JS 中的样式

    // save old window size to adjust only if width changed
    let oldWidth = window.innerWidth,
      oldHeight = window.innerHeight;
    // element to adjust
    const target = document.querySelector(".vh100");
    // adjust the size if window was resized
    window.addEventListener("resize", handleResize);
    
    function handleResize(initial = false) { // the parameter is used for calling the function on page load
      /*
       * if the width changed then resize
       * without this Chrome mobile resizes every time navbar is hidden
       */
      if (window.innerWidth !== oldWidth || initial) {
        // stretch the target
        target.classList.add("setting-100vh");
        // save height and apply as min height
        const h = target.clientHeight;
        target.classList.remove("setting-100vh");
        target.style.minHeight = h + "px";
      }
    }
    // call when page is loaded
    handleResize(true);
    * {
      margin: 0;
    }
    
    .vh100 {
      background-color: green;
    }
    
    
    /*
    * Stretch the element to window borders and save the height in JS
    */
    
    .setting-100vh {
      position: fixed;
      top: 0;
      bottom: 0;
      min-height: unset;
    }
    <body>
      <header class="vh100">
        <h1>100vh on mobile</h1>
      </header>
      <main>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus ipsa officia mollitia facilis esse cupiditate, nisi recusandae quas id enim alias eaque suscipit voluptates laudantium quasi saepe deserunt labore fuga deleniti placeat, necessitatibus
          quibusdam. Quaerat adipisci provident minima laboriosam modi ullam accusamus error dolores iure ducimus laborum similique distinctio temporibus voluptas nulla quod ipsa, nostrum quam cumque id animi unde consectetur incidunt! Dolorem sed quisquam
          at cumque. Cumque non nam exercitationem corporis? Minus sed explicabo maiores ipsam ratione. Quam, fugit asperiores nesciunt dolores culpa, numquam blanditiis sint dolorum ex corrupti illo veniam nostrum odio voluptatibus accusantium ullam impedit
          eligendi voluptates?</p>
      </main>
    </body>

    【讨论】:

      【解决方案6】:
      .my-element {
        height: 100vh; /* Fallback for browsers that do not support Custom Properties */
        height: calc(var(--vh, 1vh) * 100);
      }
      

      现在让我们在 JavaScript 中获取视口的内部高度:

      // 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`);
      

      来源:https://css-tricks.com/the-trick-to-viewport-units-on-mobile/

      【讨论】:

        【解决方案7】:

        我遇到了类似的问题,并在 ReactJS 中使用了这个解决方案:

        import { useLayoutEffect, useState } from 'react';
        
        function useWindowSize() {
          const [size, setSize] = useState([0, 0]);
          useLayoutEffect(() => {
            function updateSize() {
              setSize([window.innerWidth, window.innerHeight]);
            }
            window.addEventListener('resize', updateSize);
            updateSize();
            return () => window.removeEventListener('resize', updateSize);
          }, []);
          return size;
        }
        

        这个useWindowSize 函数取自Rerender view on browser resize with React

        当我在我的代码中使用它时,它看起来像这样:

        const MessageList = () => {
          const { messages } = useContext(ChatContext);
          const [, windowHeight] = useWindowSize();
          return (
            <div
              className="messages"
              style={{
                height: windowHeight - 80 - 48, // window - message form - navbar
              }}
            >
              {messages.map((m, i, list) => ( <Message ... /> )}
            </div>
          );
        };
        

        【讨论】:

        • 虽然这可能是一个解决方案,但我否决了它,因为您的答案需要安装和使用 React,这会打开一个全新的蠕虫罐。
        • 哇,你太棒了!你救了我这个
        【解决方案8】:

        只是想稍微扩展一下这里的最佳答案——我发现正如上面提到的 Ross Light,您想使用 height: 100% 来说明网络浏览器的地址栏。但是,要使其正常工作,您必须将 html 标记和 body 标记的高度设置为等于height: 100%,否则您的 div 将无法正确展开:

        <!DOCTYPE html>
        <html>
          <head>
        
            <style>
        
              html, body {
                height: 100%;
              }
        
              .fillViewport {
                height: 100%;
              }
        
              .redBackground {
                background-color: red;
              }
        
            </style>
        
          </head>
          <body>
        
            <div class="fillViewport redBackground"></div>
        
          <body>
        </html>
        

        【讨论】:

          【解决方案9】:

          我找到了一个不错的解决方案...

          .page-header {
            @supports (-webkit-appearance:none) {
              .os-android & {
                min-height: calc(100vh - 56px);
              }
            }
          }
          

          取自here

          【讨论】:

          • 据我了解,.os-android css 类来自 WordPress 的用户代理嗅探。所以这只能在 wordpress 中实现。
          • 这似乎不是一个好的解决方案,因为如果 chrome 突然改变了它们的标签栏高度怎么办?向后兼容性怎么样?
          猜你喜欢
          • 2016-12-22
          • 2013-04-14
          • 2016-04-22
          • 2014-12-11
          • 2018-12-02
          • 2020-06-06
          • 1970-01-01
          • 1970-01-01
          • 2011-07-09
          相关资源
          最近更新 更多