Skip to content

Instantly share code, notes, and snippets.

@bitinn
Last active September 21, 2023 20:36
Show Gist options
  • Save bitinn/1700068a276fb29740a7 to your computer and use it in GitHub Desktop.
Save bitinn/1700068a276fb29740a7 to your computer and use it in GitHub Desktop.
A soft-fullscreen prompt for iOS7+

A soft-fullscreen prompt for iOS7+

Background

iOS 7.0 and iOS 8 (Beta) do not have support for minimal-ui viewport keyword, nor do they response to window.slideTo(0,1) or support Fullscreen API, which means there is no easy way to tell Mobile Safari to hide address bar/menu without user interaction.

This is a problem for Web App that mimics Native App design, where html/body are commonly set to height: 100%, so browser viewport = available screen estate. There are currently no solution besides adding apple-mobile-web-app-capable meta and ask users to manually Save to Homescreen.

Frustrated by this limit, we present a soft-fullscreen prompt design, which, coupled with proper CSS hack, can achieve soft-fullscreen with relatively small effort from users.

Details

Below is a demo page for such design, basically, by using calc() for height, we are able to target Mobile Safari address bar height, and trigger a soft-fullscreen on user scroll.

html {
	height: calc(100% + 72px);
}

72px isn't a random number, iOS7+ UI has 44px address bar and 44px menu bar for Mobile Safari. When soft-fullscreen is triggered, its address bar collapses to 20px. So the theoretical minimum document height required to trigger hide address bar is 88px - 20px = 68px, plus the viewport height.

After testing on iOS7.1, we found that if such value is below 72px, Mobile Safari does not always hide address bar after user scroll. Thus 72px is chosen as baseline.

(Obviously there are a lot of testing needed to be done for this demo to be usable cross-device, but this demo shows we can achieve soft-fullscreen with relatively small impact on user.)

Reference

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Scroll Test</title>
<style>
html, body {
height: 100%;
}
html {
background-color: red;
}
body {
background-color: blue;
margin: 0;
}
div.header {
width: 100%;
height: 40px;
background-color: green;
overflow: hidden;
}
div.content {
height: 100%;
height: calc(100% - 40px);
width: 100%;
background-color: purple;
overflow: hidden;
}
div.cover {
position: absolute;
top: 0;
left: 0;
z-index: 100;
width: 100%;
height: 100%;
overflow: hidden;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
display: none;
}
@media screen and (width: 320px) {
html {
height: calc(100% + 72px);
}
div.cover {
display: block;
}
}
</style>
<script>
var timeout;
window.addEventListener('scroll', function(ev) {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
if (window.scrollY > 0) {
var cover = document.querySelector('div.cover');
cover.style.display = 'none';
}
}, 200);
});
</script>
</head>
<body>
<div class="header">
<p>header</p>
</div>
<div class="content">
<p>content</p>
</div>
<div class="cover">
<p>scroll to soft fullscreen</p>
</div>
</body>
</html>
@edukarma
Copy link

edukarma commented Sep 6, 2014

Demo link?

@kraftwer1
Copy link

This only seems to work as long as the content itself is not scrollable, e.g. via overflow: scroll; - right?

@yckart
Copy link

yckart commented Oct 21, 2014

@schickling
Copy link

Doesn't work for me (iPad Air I, iOS 8.1.2)

@BrendanBerkley
Copy link

Has anyone seen this work in iOS 8? I tried @yckart 's link and it didn't work for me.

@besserwisser
Copy link

Does not work for iPhone 5 iOS 10.3 ...

@mindflowgo
Copy link

Doesn't work for iOS 11. However, here is the fix, add this line to the CSS BODY:
height: calc(100% + 40px);

ex.

body {
    background-color: blue;
    margin: 0;
    height: calc(100% + 40px);
}

Now that it has some movement ability the top header will shrink and the nav at the bottom will disappear (at least in iOS 11.03 on which I tested it.).

@mindflowgo
Copy link

And and preventing touchmove the screen will now act more like an app.

Ex. if we were to use the above demo.html file, chagne the script part to this:

    <script>
              var timeout;
              window.addEventListener('scroll', function(ev) {
                      if (timeout) {
                              clearTimeout(timeout);
                      }
                      timeout = setTimeout(function() {
                              if (window.scrollY > 0) {
                                      var cover = document.querySelector('div.cover');
                                      cover.style.display = 'none';


          // and disable the touchmove features 
          window.addEventListener("touchmove", (event)=>{
              console.log( 'touchmove detected: ', event, event.target.classList );
              if (!event.target.classList.contains('scrollable')) {
                  // no more scrolling
                  event.preventDefault();
              }
          }, false); 
                              }
                      }, 200);
              });
      </script>

Final code here, try in your iPhone/iPad and tell us if it works:
http://repos.codehot.tech/misc/ios-webapp-example.html

(scan this qr-code in camera to get the above link)
image

@mindflowgo
Copy link

Signly cleaned up code:
https://repos.codehot.tech/misc/ios-webapp-example2.html

Enjoy and update us if it works for your versions of iOS!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment