├── .gitignore ├── .npmignore ├── .npmrc ├── LICENSE ├── README.md ├── cjs ├── index.js └── package.json ├── es.js ├── esm └── index.js ├── img ├── android-icon-144x144.png ├── android-icon-192x192.png ├── android-icon-36x36.png ├── android-icon-48x48.png ├── android-icon-72x72.png ├── android-icon-96x96.png ├── apple-icon-114x114.png ├── apple-icon-120x120.png ├── apple-icon-144x144.png ├── apple-icon-152x152.png ├── apple-icon-180x180.png ├── apple-icon-57x57.png ├── apple-icon-60x60.png ├── apple-icon-72x72.png ├── apple-icon-76x76.png ├── apple-icon-precomposed.png ├── apple-icon.png ├── favicon-128.png ├── favicon-16.png ├── favicon-16x16.png ├── favicon-180.png ├── favicon-192.png ├── favicon-256.png ├── favicon-32.png ├── favicon-32x32.png ├── favicon-96x96.png ├── ms-icon-144x144.png ├── ms-icon-150x150.png ├── ms-icon-310x310.png └── ms-icon-70x70.png ├── index.html ├── index.js ├── js ├── ie.js └── kindle.js ├── manifest.json ├── map └── index.html ├── min.js ├── package.json ├── rollup ├── babel.config.js └── es.config.js └── test ├── index.html ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .nyc_output 3 | node_modules/ 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .nyc_output 3 | .travis.yml 4 | node_modules/ 5 | rollup/ 6 | map/ 7 | test/ 8 | img/ 9 | index.html 10 | manifest.json 11 | js/ 12 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2020, Andrea Giammarchi, @WebReflection 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # screenfit 2 | 3 | A cross platform, cross WebView, solution to fit 100% any Web page. 4 | 5 | **[Live Demo](https://webreflection.github.io/screenfit/)** 6 | 7 | 8 | 9 | ## Usage 10 | 11 | Include *screenfit* helper on top of your *HTML* page/application: 12 | 13 | ```html 14 | 15 | ``` 16 | 17 | and optionally opt-in to listen to changes: 18 | 19 | ```js 20 | addEventListener('screenfit', ({detail}) => { 21 | const {width, height} = detail; 22 | console.log(`Now @${width}x${height}`); 23 | }); 24 | ``` 25 | 26 | It's important to include this module *ASAP* as *src*, `defer`, or `module`, as it adjusts both `` and `` styles once, so the sooner it runs, the better it is for your web/application. 27 | 28 | 29 | 30 | ## About 31 | 32 | When it comes to fullfill the current visible area of a Web page/application, nothing really works cross platform via *CSS* only, especially when the OS keyboard shows up. 33 | 34 | This module goal is to fix the ability to fullfill a screen in both `width` and, most importantly, `height`, whenever the keyboard is on the screen, or not. 35 | 36 | 37 | 38 | ## Use Cases 39 | 40 | * hero images/pages that perfectly fit on the screen even with an active keyboard 41 | * non necesasrily resizable fullscreen applications such as [Maps](https://webreflection.github.io/map/) and similar 42 | * splash screens and login splash screens 43 | * every other use case that needs 100% *HTML* area to work 44 | 45 | 46 | 47 | ## Compatibility 48 | 49 | **Works/Tested on** 50 | 51 | - KaiOS 52 | - Opera Mini 53 | - UCE Browser / Mini 54 | - Windows Phone 55 | - Samsung Internet 56 | - Android 6+ / Androind One 57 | - Any Chrome/ium based browser 58 | - Safari / Moble 13+ 59 | - Vivaldi 60 | - Firefox / Nightly 61 | - Desktop browsers, including *IE11* (see *gotchas*) 62 | 63 | **Known Gotchas** 64 | 65 | - IE11 and Kindle experimental browser need features detection (see [index.html](./index.html)) 66 | - iOS 12 (iPad does *not* trigger any resize), possible work around for iOS < 13 but not sure how to detect the available size without the keyboard: `document.addEventListener('focus', resize, true)`. If you know how to get the right height with an *iPad* on *iOS* 12 with a keyboard up, please file an issue/contact me, thank you! 67 | - Some weird edge case might use non-system related overlays that can't be detected from JS or CSS ... in that case, be sure your web/application shows most relevant informations in the center of the screen or above some known threshold 68 | -------------------------------------------------------------------------------- /cjs/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /*! (c) Andrea Giammarchi - ISC */ 3 | const { 4 | CustomEvent, 5 | addEventListener, 6 | dispatchEvent, 7 | document, 8 | scrollTo, 9 | setTimeout, 10 | visualViewport 11 | } = self; 12 | const rescroll = /Windows Phone/.test(navigator.userAgent); 13 | const detail = visualViewport || { 14 | addEventListener: addEventListener.bind(self), 15 | get width() { return self.innerWidth; }, 16 | get height() { return self.innerHeight; } 17 | }; 18 | const resize = () => { 19 | document.body.style.height = detail.height + 'px'; 20 | scrollTo(0, 0); 21 | if (rescroll) 22 | setTimeout(scrollTo, 300, 0, 0); 23 | dispatchEvent(new CustomEvent('screenfit', {detail})); 24 | }; 25 | document.head.appendChild(document.createElement('style')).textContent = 26 | 'html,body{padding:0;margin:0;overflow:hidden;box-sizing:border-box;\ 27 | height:100%;height:100vh;height:-moz-available;height:-webkit-fill-available}'; 28 | document.addEventListener('DOMContentLoaded', resize, {once: true}); 29 | detail.addEventListener('resize', resize); 30 | -------------------------------------------------------------------------------- /cjs/package.json: -------------------------------------------------------------------------------- 1 | {"type":"commonjs"} -------------------------------------------------------------------------------- /es.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict"; 2 | /*! (c) Andrea Giammarchi - ISC */const{CustomEvent:e,addEventListener:t,dispatchEvent:i,document:n,scrollTo:d,setTimeout:h,visualViewport:s}=self,o=/Windows Phone/.test(navigator.userAgent),r=s||{addEventListener:t.bind(self),get width(){return self.innerWidth},get height(){return self.innerHeight}},a=()=>{n.body.style.height=r.height+"px",d(0,0),o&&h(d,300,0,0),i(new e("screenfit",{detail:r}))};n.head.appendChild(n.createElement("style")).textContent="html,body{padding:0;margin:0;overflow:hidden;box-sizing:border-box;height:100%;height:100vh;height:-moz-available;height:-webkit-fill-available}",n.addEventListener("DOMContentLoaded",a,{once:!0}),r.addEventListener("resize",a)}(); 3 | -------------------------------------------------------------------------------- /esm/index.js: -------------------------------------------------------------------------------- 1 | /*! (c) Andrea Giammarchi - ISC */ 2 | const { 3 | CustomEvent, 4 | addEventListener, 5 | dispatchEvent, 6 | document, 7 | scrollTo, 8 | setTimeout, 9 | visualViewport 10 | } = self; 11 | const rescroll = /Windows Phone/.test(navigator.userAgent); 12 | const detail = visualViewport || { 13 | addEventListener: addEventListener.bind(self), 14 | get width() { return self.innerWidth; }, 15 | get height() { return self.innerHeight; } 16 | }; 17 | const resize = () => { 18 | document.body.style.height = detail.height + 'px'; 19 | scrollTo(0, 0); 20 | if (rescroll) 21 | setTimeout(scrollTo, 300, 0, 0); 22 | dispatchEvent(new CustomEvent('screenfit', {detail})); 23 | }; 24 | document.head.appendChild(document.createElement('style')).textContent = 25 | 'html,body{padding:0;margin:0;overflow:hidden;box-sizing:border-box;\ 26 | height:100%;height:100vh;height:-moz-available;height:-webkit-fill-available}'; 27 | document.addEventListener('DOMContentLoaded', resize, {once: true}); 28 | detail.addEventListener('resize', resize); 29 | -------------------------------------------------------------------------------- /img/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/android-icon-144x144.png -------------------------------------------------------------------------------- /img/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/android-icon-192x192.png -------------------------------------------------------------------------------- /img/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/android-icon-36x36.png -------------------------------------------------------------------------------- /img/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/android-icon-48x48.png -------------------------------------------------------------------------------- /img/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/android-icon-72x72.png -------------------------------------------------------------------------------- /img/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/android-icon-96x96.png -------------------------------------------------------------------------------- /img/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/apple-icon-114x114.png -------------------------------------------------------------------------------- /img/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/apple-icon-120x120.png -------------------------------------------------------------------------------- /img/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/apple-icon-144x144.png -------------------------------------------------------------------------------- /img/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/apple-icon-152x152.png -------------------------------------------------------------------------------- /img/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/apple-icon-180x180.png -------------------------------------------------------------------------------- /img/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/apple-icon-57x57.png -------------------------------------------------------------------------------- /img/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/apple-icon-60x60.png -------------------------------------------------------------------------------- /img/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/apple-icon-72x72.png -------------------------------------------------------------------------------- /img/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/apple-icon-76x76.png -------------------------------------------------------------------------------- /img/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/apple-icon-precomposed.png -------------------------------------------------------------------------------- /img/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/apple-icon.png -------------------------------------------------------------------------------- /img/favicon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/favicon-128.png -------------------------------------------------------------------------------- /img/favicon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/favicon-16.png -------------------------------------------------------------------------------- /img/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/favicon-16x16.png -------------------------------------------------------------------------------- /img/favicon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/favicon-180.png -------------------------------------------------------------------------------- /img/favicon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/favicon-192.png -------------------------------------------------------------------------------- /img/favicon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/favicon-256.png -------------------------------------------------------------------------------- /img/favicon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/favicon-32.png -------------------------------------------------------------------------------- /img/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/favicon-32x32.png -------------------------------------------------------------------------------- /img/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/favicon-96x96.png -------------------------------------------------------------------------------- /img/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/ms-icon-144x144.png -------------------------------------------------------------------------------- /img/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/ms-icon-150x150.png -------------------------------------------------------------------------------- /img/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/ms-icon-310x310.png -------------------------------------------------------------------------------- /img/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/screenfit/b1aaeac96ef85b27c969931f756cc0dbfe6e5ccd/img/ms-icon-70x70.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | screenfit live demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 68 | 69 | 70 | 71 | 82 | 83 | 84 |
85 | 86 |
87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | /*! (c) Andrea Giammarchi - ISC */ 5 | var _self = self, 6 | CustomEvent = _self.CustomEvent, 7 | addEventListener = _self.addEventListener, 8 | dispatchEvent = _self.dispatchEvent, 9 | document = _self.document, 10 | scrollTo = _self.scrollTo, 11 | setTimeout = _self.setTimeout, 12 | visualViewport = _self.visualViewport; 13 | var rescroll = /Windows Phone/.test(navigator.userAgent); 14 | var detail = visualViewport || { 15 | addEventListener: addEventListener.bind(self), 16 | 17 | get width() { 18 | return self.innerWidth; 19 | }, 20 | 21 | get height() { 22 | return self.innerHeight; 23 | } 24 | 25 | }; 26 | 27 | var resize = function resize() { 28 | document.body.style.height = detail.height + 'px'; 29 | scrollTo(0, 0); 30 | if (rescroll) setTimeout(scrollTo, 300, 0, 0); 31 | dispatchEvent(new CustomEvent('screenfit', { 32 | detail: detail 33 | })); 34 | }; 35 | 36 | document.head.appendChild(document.createElement('style')).textContent = 'html,body{padding:0;margin:0;overflow:hidden;box-sizing:border-box;\ 37 | height:100%;height:100vh;height:-moz-available;height:-webkit-fill-available}'; 38 | document.addEventListener('DOMContentLoaded', resize, { 39 | once: true 40 | }); 41 | detail.addEventListener('resize', resize); 42 | 43 | }()); 44 | -------------------------------------------------------------------------------- /js/ie.js: -------------------------------------------------------------------------------- 1 | !function(a){a.write(' 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | require('../cjs'); -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | {"type":"commonjs"} --------------------------------------------------------------------------------