可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Our mobile web application has sticky bottom navigation like the one you often find in iOS applications, and after Safari 10.3 release on landscape only it is possible to scroll sticky navigation (footer) off the screen. Even though it is position: fixed
and set bottom: 0
it also wasn't possible on older Safari versions.
Styles for sticky nav / footer are following:
footer {
position: fixed;
height: 50px;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 0, 0, 0.7);
}
DEMO to try on phone
In portrait mode it is always visible:
In landscape mode you can scroll it off screen for the size of top address bar:
Has anyone come across such issue? I would appreciate any help to make footer stay on the screen. Thanks
回答1:
There is nothing you can do about it. Safari's landscape mode makes the container with your content going off the screen. This is not detectable and therefore not to solve. I tried to illustrate what happens:
The blue bar = Safari's navigation bar
The yellow bar = Your app's navigation bar
Instead of shrinking the container's height, Safari lets it go off the screen.
回答2:
This is more a workaround than a real solution. However position: fixed
has been a problem for mobile devices for years and the best way to overcome this problem is to use position: sticky
.
sticky
behaves like position: relative
within its parent, until a
given offset threshold is met in the viewport.
From: Stick your landings! position: sticky lands in WebKit
However position: sticky
is not fully supported yet, so I would suggest to use also:
position: sticky; /* currently in development for MS Edge */
position: -webkit-sticky;
position: -moz-sticky;
position: -o-sticky;
See status here for MS Edge sticky
support status (thank you Frits)
html,
body {
height: 200%;
}
body {
background-image: linear-gradient(180deg, #ededed 0px, #ededed 9px, #000000 9px, #000000 10px);
background-size: 100% 10px;
}
footer {
position: sticky; /* currently in development for MS Edge */
position: -webkit-sticky;
position: -moz-sticky;
position: -o-sticky;
height: 50px;
top: 80%;
background: rgba(255, 0, 0, 0.7);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<footer>
</footer>
</body>
</html>
回答3:
There is another way of creating a fixed element at the bottom of the page:
Set the <body>
element (or whatever wraps your header, content and footer) to display: flex; height: 100vh
. Then you take the footer and set it to margin-top: auto
.
HTML:
<body>
<header>
</header>
<main>
<main>
<footer>
</footer>
</body>
CSS:
html {
height: 100%;
}
body {
height: 100%;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
A different solution with the same markup would be to use CSS Grid:
html {
height: 100%;
}
body {
height: 100%;
display: grid;
grid-template-rows: auto 1fr auto;
}
In order to get the best of both worlds you can wrap the CSS Grid styles in an @supports(display: grid){}
wrapper. If Grid is supported the browser will take that and otherwise will fallback to Flexbox.
The best thing using this technique is that you won't run into overlapping contents, into zooming-issues and it is fully responsive from the get-go.
There is an article on CSS Tricks about the subject: https://css-tricks.com/couple-takes-sticky-footer/
回答4:
Try this on the fixed position element in your css:
transform:translate3d(0px, 0, 0);
-webkit-transform:translate3d(0px, 0, 0);
回答5:
I had the same problem and I fixed it in a way that my tester is happy.
Not a perfect solution but doing its job.
Add an empty element with some padding or margin.
const _userAgent = navigator.userAgent.toLowerCase();
if (_userAgent.indexOf('safari') != -1) {
if (_userAgent.indexOf('chrome') == -1) {
$('.myelem').append('<div class="my-5"></div>');
}
}
回答6:
Something that does happen on the switch to landscape mode, and the switch to and from safari's 'minimal UI' is a window resize event. You can check the getBoundingClientRect().bottom
of the fixed element to see if it is greater than window.innerHeight
(This means the fixed element is off of the bottom of the window). If so, you can set the css property bottom
of the fixed
element to element.getBoundingClientRect().bottom - window.innerHeight
. This will maintain to position of the fixed element. It appears to be a little jank to the user, but this is better than the element going off of the bottom of the screen.