Html 防止固定位置背景图像:在地址栏隐藏时在移动浏览器中调整封面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23299960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 01:38:44  来源:igfitidea点击:

Prevent fixed-position background-image: cover from resizing in mobile browsers upon address bar hide

htmlcssbackground-imagemobile-browsercover

提问by addMitt

Sorry for a lack of example on this one, but I figure it's easy enough to understand.

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

I have a fixed background on my site, which is currently implemented like this:

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

#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>

This is great in all browsers so far except for mobile browsers where they hide the address bar upon scroll-down. When the address bar is hidden, the viewport expands vertically, and the background-image jarringly resizes itself. On this particular site it will be common for users to scroll up and down, and the effect is distracting.

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

Any ideas or strategies on working around this or implementing the background in a different way?

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

I could wrap the entire thing in a fixed container, and set the overflow-y to scroll, which prevents the address bar from ever being hidden, but I'd prefer not to do this (Google Glass can't scroll through those containers, haha... Would like to demo on there as well).

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

I've been trying to think of something that provides background-image: cover functionality with some sort of buffer, so that it renders larger than the viewport, and won't re-render unless the viewport is expanded beyond that buffer, but I'm not sure how to implement that.

我一直在想一些提供背景图像的东西:用某种缓冲区覆盖功能,以便它呈现大于视口,并且除非视口扩展到该缓冲区之外,否则不会重新呈现,但我不知道如何实现。

EDIT: I actually did implement this and detailed the process in an answer below. However, even with this buffer setup (which extends the height of the background image to be 60+ pixels larger than the viewport height), upon the address bar hiding, it still shows a blank background-color segment that gets revealed, and once you stop scrolling, it renders the rest of the background image.

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

Still looking for a way to keep the native address bar hide functionality (which has now been expanded to iOS Safari on iPad in iOS 8), and also have a fullscreen background image that always fully renders even if the viewport changes height when hiding the address bar. Starting to wonder if I should just be filing bug reports for all the browsers...

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

采纳答案by addMitt

Almost 5 years later, there is finally a fix for this, due to changes in how Safari and now Chrome for Android calculate vh units. Check it out! https://developers.google.com/web/updates/2016/12/url-bar-resizing

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

I implemented it on this website (can't really show this off on any of the code playgrounds due to them always embedding results in iframes): https://www.cochranesupply.com

我在这个网站上实现了它(无法在任何代码操场上展示这一点,因为它们总是在 iframe 中嵌入结果):https: //www.cochranesupply.com

Just used the following code on a background element:

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

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

And that's all there is to it! Just need Chrome for Android 56, or Safari for iOS (not certain which version but this may have been in Safari for a long time now).

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

回答by addMitt

I ended up creating a workaround for mobile. It may not degrade gracefully, but it's working well for the time being.

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

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);
 }

I found that mobilecheck function on the internet ( http://detectmobilebrowsers.com/). If it returns true, I take my fixed background image container and add 70 to its height. Then when you drag the screen up and the web browser's address bar auto-hides (thus increasing the window height), it has enough extra height such that background-size: cover does not have to jarringly resize the background image to fit the screen again.

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

I could have just put the entire page into a fixed container and prevented mobile address bars from ever hiding, but I don't like sidestepping an otherwise neat feature of mobile browsers, and I know iOS isn't exactly thrilled with fixed containers that have their own scrollbars (there are workarounds of course, but I'd prefer my content to be in a more standard container).

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

EDIT: However, this workaround introduces this issue: CSS CHALLANGE: Background-Image with 100% height - White Space when Scrolling Mobile

编辑:然而,这个解决方法引入了这个问题:CSS CHALLANGE: Background-Image with 100% height - White Space when Scrolling Mobile

回答by Michael Morris

For mobile safari you must, unintuitively, attach fixed backgrounds to the html element like so.

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

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

Then set the scrolling to the body.

然后将滚动设置为正文。

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

You'll still need the background div for IE 8 since it doesn't support the background-size property, so mobile browsers should hide it. The cleanest way to do this is to exploit IE 8's inability to read a media query

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

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

回答by tjklemz

For those still looking around for an answer, you can use the new vwand vhattributes with an element that is position: fixed.

对于那些仍在四处寻找答案的人,您可以将 newvwvh属性与position: fixed.

This scrolls while the address bar moves/shrinks/etc., then remains fixed on the page.

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

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

回答by Mike Arledge

I made this. I found that if you never really scroll the body/window you never trigger the autohide for Chrome. So wrap the content in a bigger div and just scroll that and the autohide never triggers. BUT ALSO!!! The autohide never triggers. (Address bar is always there). Wouldn't doubt for second you could hide the address bar after this but then how does the user get the address bar back?

我做的。我发现如果你从来没有真正滚动过身体/窗口,你就永远不会触发 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>

回答by xno

Its hard to say without an example but you may be missing width:100%that should stop any resizing with the scroll bar.

没有示例很难说,但您可能会遗漏width:100%应该停止使用滚动条调整大小的内容。

Another way to implement a fixed background on mobile is to have a background div with position: absoluteand overflow: hiddenand all your other background implementations, Then have a content div with overflow-y:scroll;and set the height of the content div using jquery or any other method you choose to get the window height with.

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

Check out this JS Fiddlefor an example.

以这个JS Fiddle为例。