【问题标题】:Prevent fixed-position background-image: cover from resizing in mobile browsers upon address bar hide防止固定位置的背景图像:地址栏隐藏时在移动浏览器中调整封面大小
【发布时间】:2014-06-11 13:43:24
【问题描述】:

抱歉,这方面的例子很少,但我认为它很容易理解。

我的网站有一个固定的背景,目前是这样实现的:

#background {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: #28305e;
    background-image: url(../images/background.jpg);
    background-size: cover;
    -moz-background-size: cover;
    background-position: center center;
    z-index: -10;
}

<div id="background"></div>

到目前为止,这在所有浏览器中都很棒,除了移动浏览器,它们在向下滚动时会隐藏地址栏。当地址栏被隐藏时,视口会垂直扩展,背景图像会自行调整大小。在这个特定的网站上,用户通常会上下滚动,而且效果会分散注意力。

关于解决此问题或以不同方式实现背景的任何想法或策略?

我可以将整个内容包装在一个固定的容器中,并将溢出-y 设置为滚动,这样可以防止地址栏被隐藏,但我不想这样做(Google Glass 无法滚动浏览那些容器,哈哈……也想在那里演示)。

我一直在尝试提供背景图像:使用某种缓冲区覆盖功能,以便它呈现大于视口,并且除非视口扩展超出该缓冲区,否则不会重新渲染,但我不确定如何实现。

编辑:我确实实现了这一点,并在下面的答案中详细说明了该过程。但是,即使使用此缓冲区设置(将背景图像的高度扩展为比视口高度大 60+ 像素),在地址栏隐藏时,它仍然会显示一个空白的背景色段,并且一旦你停止滚动,它会渲染背景图像的其余部分。

仍在寻找一种方法来保持本机地址栏隐藏功能(现已在 iOS 8 中扩展到 iPad 上的 iOS Safari),并且还有一个全屏背景图像,即使视口改变高度时也始终完全呈现隐藏地址栏。开始怀疑我是否应该为所有浏览器提交错误报告...

【问题讨论】:

  • 这已经成为一个更大的问题,因为 iPad 上的 iOS 8 上的 Safari 现在做了同样的事情:向下滚动时缩小浏览器标题。
  • 嘿@addMitt,似乎没有一个解决方案能完美运行。你找到解决这个问题的方法了吗?
  • 我没有,最近的测试表明同样的问题仍然存在。我已经停止开发具有全屏背景图像的移动页面。这将正常工作的唯一方法是,如果我们被允许使固定容器大于视口高度,并且当您向下滚动并隐藏地址栏时,浏览器会正确呈现背景图像的其余部分,而不是将其显示为完全白色,直到您停止滚动。然而,这需要在浏览器中修复。

标签: html css background-image mobile-browser cover


【解决方案1】:

将近 5 年后,由于 Safari 和现在的 Android 版 Chrome 计算 vh 单位的方式发生了变化,终于有了解决此问题的方法。看看这个! https://developers.google.com/web/updates/2016/12/url-bar-resizing

我在这个网站上实现了它(由于它们总是将结果嵌入 iframe,因此无法在任何代码游乐场上真正展示它):https://www.cochranesupply.com

刚刚在背景元素上使用了以下代码:

#background {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    background-image: url(../images/background.jpg);
    background-size: cover;
    z-index: -1;
}

仅此而已!只需要适用于 Android 56 的 Chrome 或适用于 iOS 的 Safari(不确定是哪个版本,但这可能已经在 Safari 中存在很长时间了)。

【讨论】:

  • 这在适用于 Android 的 Chrome 上运行良好,非常感谢!不幸的是,这个问题在最新的 Firefox for Android 上仍然存在。有什么建议可以在 Firefox 上修复它吗?
  • 截至 2020 年 7 月,这确实适用于 Android 中的 Chrome、iOS 中的 Safari,并且我假设所有基于 webkit/blink 的浏览器(Edge、Opera 等)。但它在 Firefox 中不起作用。
  • 如果您只有一个固定背景,这是一个很好的解决方案,但如果您尝试具有多个固定背景的视差效果(很像this example),那么您可能会直接退出运气。
  • Android 上的 Firefox 最近推出了一项新功能,允许用户将地址栏放在底部。到目前为止,它看起来对这种情况有所帮助。
【解决方案2】:

我最终为移动设备创建了一个解决方法。它可能不会优雅地降级,但目前运行良好。

window.mobilecheck = function() {
  var check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|android|ipad|playbook|silk|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
 }

 if (window.mobilecheck() == true) {
  var newHeight = $(window).height() + 70;
  $("#background").css("height", newHeight);
 }

我在网上找到了 mobilecheck 功能(http://detectmobilebrowsers.com/)。如果它返回 true,我将使用我的固定背景图像容器并将其高度添加 70。然后,当您向上拖动屏幕并且网络浏览器的地址栏自动隐藏(从而增加窗口高度)时,它具有足够的额外高度,因此 background-size:cover 不必调整背景图像的大小以再次适合屏幕.

我本可以将整个页面放入一个固定的容器中并防止移动地址栏隐藏,但我不喜欢回避移动浏览器的其他简洁功能,而且我知道 iOS 并不完全喜欢固定有自己的滚动条的容器(当然有变通方法,但我希望我的内容放在更标准的容器中)。

编辑:但是,此解决方法引入了此问题:CSS CHALLANGE: Background-Image with 100% height - White Space when Scrolling Mobile

【讨论】:

    【解决方案3】:

    对于移动 safari,您必须像这样不直观地将固定背景附加到 html 元素。

    html {
        background: url(../img/bg.jpg) no-repeat center center fixed;
        background-size: cover;
        height: 100%;
        overflow: hidden;
    }
    

    然后设置滚动到body。

    body {
        height: 100%;
        overflow: scroll;
    }
    

    您仍然需要 IE 8 的背景 div,因为它不支持 background-size 属性,因此移动浏览器应该隐藏它。最简洁的方法是利用 IE 8 无法读取媒体查询

    @media only screen { #background { display: none; }}
    

    【讨论】:

    • 这不会阻止 BG 图像在显示/隐藏 url-bar 时调整大小。它停止显示/隐藏 url-bar。它还消除了惯性滚动。
    【解决方案4】:

    对于那些仍在四处寻找答案的人,您可以将新的 vwvh 属性与 position: fixed 元素一起使用。

    当地址栏移动/缩小/等时滚动,然后保持固定在页面上。

    #bgimg {
      display: block;
      background: no-repeat url(bg.png);
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      height: 120vh;
    }
    

    【讨论】:

    • 不幸的是,当使用背景大小的封面时,这仍然无法解决此处列出的问题:stackoverflow.com/questions/23776999/… 当它滚动时,它会显示一个空白的背景色空间,然后在您停止滚动后填充(至少在 iOS Safari 上)。
    • 好的。很高兴知道...在 Android 的 Chrome 中,这很好用。我将不得不在 iOS 上进行测试。谢谢。
    • 我可以确认它在不显示 Android Chrome 中的背景颜色的情况下显示自己(现在......几个月前它没有这样做,哈哈)。但是,每当由于地址栏的隐藏而调整视口高度时, background-size:cover 会再次触发,并将自身拉伸到当前视口高度的 120vh。这意味着每次您向上/向下滚动背景图像时都会不和谐地调整自身大小(回到原来的问题!@_@)
    • 它在 Lollipop 上最新的 Android Chrome 上非常适合我。如果这在 KitKat 上不起作用,我不会感到惊讶。 :P
    • 我正在使用带有 Lollipop 的 Nexus 5 和最新的 Chrome。你在使用背景尺寸:封面吗?您的答案未包含在 CSS 中。
    【解决方案5】:

    没有示例很难说,但您可能缺少width:100%,它应该停止使用滚动条调整大小。

    在移动设备上实现固定背景的另一种方法是有一个带有position: absoluteoverflow: hidden 的背景div 以及所有其他背景实现,然后有一个带有overflow-y:scroll; 的内容div 并设置内容div 的高度使用 jquery 或您选择的任何其他方法来获取窗口高度。

    查看此JS Fiddle 以获取示例。

    【讨论】:

    • 更多的是关于 background-size:cover 的工作原理,它在哪里拍摄和图像并使其适合,同时保持图像纵横比。因此,如果您有一个纵向视口,它将使图像居中,将其放大直到适合垂直分辨率,并允许裁剪图片的水平边缘。我喜欢这个功能,但由于前面描述的行为,每次移动浏览器增加视口大小并隐藏其地址栏时,它都会调整大小。
    • 仍然可以添加一个 div 容器来保存和滚动您的内容,正如我上面解释的那样,滚动不会在您的背景 div 中发生 - 因此不会调整您的图像大小。我没有建议你用background-size:cover 改变任何东西。只需将滚动添加到位于背景 div 顶部的 div,这样它就不会在滚动条出现时干扰。另外,我认为您的编辑包含与您的原件无关的问题,您应该单独询问以获得准确的答案。
    【解决方案6】:

    这是我做的。我发现如果你从不真正滚动正文/窗口,你永远不会触发 Chrome 的自动隐藏。所以将内容包装在一个更大的 div 中,然后滚动它,自动隐藏永远不会触发。但是也!!!自动隐藏永远不会触发。 (地址栏始终存在)。毫无疑问,您可以在此之后隐藏地址栏,但是用户如何取回地址栏?

    html, body {
      height: 100%; 
      overflow: hidden;
    }
    body {
      height: 100%;
    }
    #background {
      position: fixed;
      left: 50%;
      bottom: 0px;
      min-width: 100%;
      min-height: 120%;
      z-index: 0;
      background: url('background.gif');
      margin-left: -50%;
      background-position: center center;
      background-attachment: fixed;  
      background-size: cover;
    }
    #main_container {
      width: inherit;
      height: inherit;
      overflow-y: scroll;
    }
    .block {
      position: relative;
      text-align: center;
      background: transparent;
      height: 100%;
      z-index: 9;
    }
    .block {
      width: 100%;
      height: 100%;
      background: rgba(224, 224, 224, 0.4);
    }
    .block::before {
      content: '';
      display: inline-block;
      height: 100%; 
      vertical-align: middle;
    }
    .centered {
      display: inline-block;
      vertical-align: middle;
    }
    
    <div id="main_container">
      <div class="block" >
        <div class="centered">
          <h1 class="circle">Some text</h1>
        </div>
      </div>
      <div class="block">  
        <div class="centered">
          <h1>Some text</h1>
        </div>
      </div>
      <div class="block">  
        <div class="centered">
          <h1>Some text</h1>
        </div>
      </div>
      <div class="block">  
        <div class="centered">
          <h1>Some text</h1>
        </div>
      </div>
      <div class="block" >
        <div class="centered">
          <h1>Some text</h1> 
        </div>
      </div>
    </div>
    <div id="bg"></div>
    

    【讨论】:

    • 欢迎来到 Stack Overflow!看起来是一个很好的答案!好的。但是,您的最后一句话看起来像一个问题。您的意思是说用户无法获得 A.B. (我假设地址栏)回来了?如果您不确定,最好说“但是如果您可以让它消失,我不确定您是否可以取回它。”
    • 感谢 Glut。是的,这是一个问题。如果你制作 A.B. (地址栏)消失要做什么才能获得 A.B.重新出现。希望有帮助。 ib想要了解的最重要的一点是地址栏不会使用这种技术隐藏。
    • 这就是为什么我一直犹豫接受任何答案。唯一的解决方法是完全防止它隐藏。理想情况下,会有一个解决方案允许自动隐藏,也允许背景图像的新暴露部分(设置为“cover”)正确渲染,而不是稍后的空白空间停止滚动时填写。
    猜你喜欢
    • 2021-01-07
    • 2013-08-06
    • 1970-01-01
    • 2016-10-28
    • 2013-08-10
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多