web-dev-qa-db-fra.com

iOS 8 a supprimé la propriété de fenêtre d'affichage "minimal-ui". Existe-t-il d'autres solutions "soft fullscreen"?

(Ceci est une question en plusieurs parties, je ferai de mon mieux pour résumer le scénario.)

Nous sommes en train de créer une application Web réactive (lecteur de nouvelles) qui permet aux utilisateurs de glisser d'un contenu à l'autre, ainsi que de faire défiler verticalement chaque contenu.

Une approche courante du problème consiste à avoir un wrapper div qui remplit la fenêtre du navigateur, définissez overflow sur hidden ou auto, puis faites défiler horizontalement et/ou verticalement à l'intérieur. .

Cette approche est intéressante mais présente un inconvénient principal: , car la hauteur du document est identique à celle de la fenêtre de visualisation du navigateur, le navigateur mobile ne masque pas la barre d’adresse/le menu de navigation .

Il existe nombreux hacks et propriétés de viewport qui nous permettent d’obtenir plus d’écran, mais aucun n’est aussi efficace que minimal-ui (introduit dans iOS 7.1).

La nouvelle est arrivée hier qu'iOS 8 beta4 avait supprimé minimal-ui de Mobile Safari (voir la section Webkit dans Notes de version iOS 8 ), ce qui nous laissait perplexe:

Q1. Est-il encore possible de cacher la barre d'adresse sur Mobile Safari?

Autant que nous sachions, iOS 7 ne répond plus au window.scrollTo bidouille, cela suggère que nous devons vivre avec le plus petit espace d'écran, à moins d'adopter une disposition verticale ou d'utiliser mobile-web-app-capable.

Q2. Est-il encore possible d'avoir une expérience similaire en plein écran doux?

Par plein écran souple , je veux vraiment dire sans utiliser la balise méta mobile-web-app-capable.

Notre application Web est conçue pour être accessible. Toute page peut être marquée ou partagée à l'aide du menu du navigateur natif. En ajoutant mobile-web-app-capable, nous empêchons les utilisateurs d’appeler un tel menu (lorsqu’il est enregistré sur l’écran d’accueil), ce qui confond et antagonise les utilisateurs.

minimal-ui était autrefois le milieu, masquant le menu par défaut mais le rendant accessible en un clic - bien que Apple l'ait peut-être supprimé en raison d'une autre accessibilité problèmes (tels que les utilisateurs ne sachant pas où appuyer pour activer le menu).

Q3. Une expérience en plein écran vaut-elle la peine?

Il semblerait qu'un API plein écran ne soit pas bientôt disponible sur iOS, mais même si c'est le cas, je ne vois pas comment le menu restera accessible (même chose pour Chrome sur Android).

Dans ce cas, nous devrions peut-être laisser le safari mobile en l'état et prendre en compte la hauteur de la fenêtre (pour l'iPhone 5+, il s'agit de 460 = 568 - 108, où 108 inclut la barre de système d'exploitation, la barre d'adresse et le menu de navigation; pour iPhone 4 ou plus vieux, il est 372).

J'aimerais entendre quelques alternatives (en plus de la construction d'une application native).

182
bitinn

La propriété d'affichage minimal-ui est n'est plus prise en charge sous iOS 8. Cependant, l'interface minimale elle-même n'est pas partie. L'utilisateur peut entrer le minimum-ui avec un geste de "toucher-glisser vers le bas".

Plusieurs conditions et obstacles sont nécessaires à la gestion de l'état d'affichage, par exemple: Pour que minim-ui fonctionne, il doit y avoir suffisamment de contenu pour permettre à l'utilisateur de faire défiler l'écran. pour que minimal-ui persiste, le défilement de la fenêtre doit être décalé au chargement de la page et après le changement d'orientation. Cependant, il n'y a aucun moyen de calculer les dimensions de l'interface minimale-ui en utilisant la variable screen, et donc aucun moyen de savoir si l'utilisateur se trouve dans l'unité minimale à l'avance.

Ces observations sont le résultat de recherches dans le cadre du développement Gestionnaire de vues de bord pour iOS 8. La mise en œuvre finale fonctionne de la manière suivante:

Lorsque la page est chargée, Brim crée un élément de tapis de course. L'élément Tapis de course est utilisé pour donner à l'utilisateur un espace de défilement. La présence de l’élément du tapis de course garantit que l’utilisateur peut entrer dans la vue minimal-ui et qu’elle continue à persister s’il recharge la page ou modifie l’orientation du périphérique. Il est invisible pour l'utilisateur tout le temps. Cet élément a l'ID brim-treadmill.

Lors du chargement de la page ou après avoir changé l’orientation, Brim utilise Scream pour détecter si la page se trouve dans la vue minimal-ui (la page qui était précédemment dans minimal-ui et qui a été rechargée restera dans la minimal-ui si la hauteur du contenu est supérieure à la hauteur de la fenêtre).

Quand la page est dans le minimum-interface utilisateur, Brim désactive le défilement du document (il le fait de manière sans danger qui n’affecte pas le contenu de l’élément principal). La désactivation du défilement des documents évite de laisser accidentellement le minimum-ui lors du défilement vers le haut. Conformément aux spécifications iOS 7.1 d'origine, taper sur la barre supérieure ramène le reste du chrome.

Le résultat final ressemble à ceci:

Brim in iOS simulator.

Par souci de documentation et si vous préférez écrire votre propre implémentation, il est à noter que vous ne pouvez pas utiliser Scream pour détecter si le périphérique est en mode minimal-ui juste après le orientationchange événement car les dimensions window ne reflètent pas la nouvelle orientation jusqu'à la fin de l'animation de rotation. Vous devez associer un écouteur à l'événement orientationchangeend .

Scream et orientationchangeend ont été développés dans le cadre de ce projet.

82
Gajus

Comme il n’existe aucun moyen programmé d’imiter minimal-ui, nous avons proposé une solution de contournement différente en utilisant calc() et une hauteur de barre d’adresse iOS connue à notre avantage:

La page de démonstration suivante ( également disponible sur Gist, plus de détails techniques ici ) invitera l'utilisateur à faire défiler l'écran, ce qui déclenche ensuite un affichage en mode plein écran (masquer la barre d'adresse/le menu), où l'en-tête et le contenu remplissent la nouvelle fenêtre d'affichage.

<!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>
20
bitinn

Il suffit de dire au revoir à minimal-ui (pour l'instant)

Il est vrai que minimal-ui pourrait être à la fois utile et nuisible, et je suppose que le compromis a maintenant un autre équilibre, en faveur des iPhones plus récents et plus grands.

Je me suis occupé de ce problème tout en travaillant avec mon framework js pour les applications HTML5. Après de nombreuses tentatives de solutions, chacune avec leurs inconvénients, je me suis rendu compte que l'espace perdu sur les iPhones était inférieur à 6. Compte tenu de la situation, je pense que le seul comportement solide et prévisible est un comportement prédéterminé.

En bref, j'ai fini par empêcher toute forme de minimum-ui , donc au moins la hauteur de mon écran est toujours la même et vous savez toujours quel est l'espace réel avoir pour votre application.

Avec le temps, suffisamment d'utilisateurs auront plus de place.


MODIFIER

Comment je le fais

Ceci est un peu simplifié, à des fins de démonstration, mais devrait fonctionner pour vous. En supposant que vous ayez un conteneur principal

html, body, #main {
  height: 100%;
  width: 100%;
  overflow: hidden;
}
.view {
  width: 100%;
  height: 100%;
  overflow: scroll;
}

Ensuite:

  1. puis avec js, je règle la hauteur de #main sur la hauteur disponible de la fenêtre. Cela aide également à traiter les autres bogues de défilement trouvés dans iOS et Android. Cela signifie également que vous devez déterminer comment le mettre à jour, notez simplement cela;

  2. Je bloque le défilement lorsque j'atteins les limites du défilement. Celui-ci est un peu plus profond dans mon code, mais je pense que vous pouvez aussi bien suivre le principe de cette réponse pour les fonctionnalités de base. Je pense que cela pourrait un peu flickr, mais fera le travail.


Voir la démo (sur un iPhone)

Comme une remarque: cette application est aussi bookmarkable, car elle utilise un routage interne pour les adresses hachées, mais j'ai également ajouté un invite utilisateurs iOS à ajouter à la maison. Je pense que cela aide à fidéliser et à faire revenir les visiteurs (et donc l'espace perdu est de retour).

9
Francesco Frapporti

Le moyen le plus simple que j'ai trouvé pour résoudre ce problème consistait à définir la hauteur des éléments body et html sur 100,1% pour toute demande dans laquelle l'agent utilisateur était un iphone. Cela ne fonctionne qu'en mode Paysage, mais c'est tout ce dont j'avais besoin.

html.iphone, 
html.iphone body { height: 100.1%; }

Vérifiez-le à https://www.360jungle.com/virtual-tour/25

7
Stephen Garside

Le problème racine ici semble que iOS8 safari ne cachera pas la barre d'adresse lors du défilement vers le bas si le contenu est égal ou inférieur à la fenêtre d'affichage.

Comme vous l'avez déjà constaté, ajouter un peu de remplissage en bas résout ce problème:

html {
    /* enough space to scroll up to get fullscreen on iOS8 */
    padding-bottom: 80px;
}
// sort of emulate safari's "bounce back to top" scroll
window.addEventListener('scroll', function(ev) {
    // avoids scrolling when the focused element is e.g. an input
    if (
        !document.activeElement
        || document.activeElement === document.body
    ) {
        document.body.scrollIntoViewIfNeeded(true);
    }
});

Le css ci-dessus doit être appliqué de manière conditionnelle, par exemple avec UA Sniffing ajoutant une classe gt-ios8 à <html>.

2
Razor

C’est IS possible, en utilisant quelque chose comme l’exemple ci-dessous que j’ai assemblé à l’aide du travail de ( https://Gist.github.com/bitinn/1700068a276fb29740a7 ) qui n’a pas tout à fait travailler sur iOS 11:

Voici le code modifié qui fonctionne sur iOS 11.03, veuillez indiquer si cela a fonctionné pour vous.

La clé ajoute de la taille à BODY pour que le navigateur puisse défiler, par exemple: hauteur: calc (100% + 40px);

Échantillon complet ci-dessous et lien à afficher dans votre navigateur (veuillez tester!)

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CodeHots iOS WebApp Minimal UI via Scroll Test</title>

    <style>
        html, body {
            height: 100%;
        }
        html {
            background-color: red;
        }
        body {
            background-color: blue;
            /* important to allow page to scroll */
            height: calc(100% + 40px);
            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;

        function interceptTouchMove(){
            // and disable the touchmove features 
            window.addEventListener("touchmove", (event)=>{
                if (!event.target.classList.contains('scrollable')) {
                    // no more scrolling
                    event.preventDefault();
                }
            }, false); 
        }

        function scrollDetect(event){
            // wait for the result to settle
            if( timeout ) clearTimeout(timeout);

            timeout = setTimeout(function() {
                console.log( 'scrolled up detected..' );
                if (window.scrollY > 35) {
                    console.log( ' .. moved up enough to go into minimal UI mode. cover off and locking touchmove!');
                    // hide the fixed scroll-cover
                    var cover = document.querySelector('div.cover');
                    cover.style.display = 'none';

                    // Push back down to designated start-point. (as it sometimes overscrolls (this is jQuery implementation I used))
                    window.scrollY = 40;

                    // and disable the touchmove features 
                    interceptTouchMove();

                    // turn off scroll checker
                    window.removeEventListener('scroll', scrollDetect );                
                }
            }, 200);            
        }

        // listen to scroll to know when in minimal-ui mode.
        window.addEventListener('scroll', scrollDetect, false );
    </script>
</head>
<body>

    <div class="header">
        <p>header zone</p>
    </div>
    <div class="content">
        <p>content</p>
    </div>
    <div class="cover">
        <p>scroll to soft fullscreen</p>
    </div>

</body>

Exemple de lien complet ici: https://repos.codehot.tech/misc/ios-webapp-example2.html

1
Code Freeze

Je veux commenter/répondre partiellement/partager mes pensées. J'utilise la technique de débordement-y: scroll pour un de mes grands projets à venir. Son utilisation présente deux avantages MAJEURS.

a) Vous pouvez utiliser un tiroir avec des boutons d’action situés en bas de l’écran; Si le document défile et que la barre inférieure disparaît, il suffit d'appuyer sur un bouton situé au bas de l'écran pour afficher la barre inférieure, puis de cliquer dessus. De plus, la façon dont cette chose fonctionne crée des problèmes avec les modaux qui ont des boutons tout en bas.

b) Lors de l'utilisation d'un élément survolé, les seules choses qui sont repeintes en cas de modifications majeures du CSS sont celles affichées à l'écran. Cela m'a permis d'améliorer considérablement les performances lors de l'utilisation de javascript pour modifier le css de plusieurs éléments à la volée. Par exemple, si vous avez besoin de repeindre une liste de 20 éléments et que seuls deux d’entre eux sont affichés à l’écran dans l’élément survolé, seuls ceux-ci sont repeints tandis que les autres sont repeints lors du défilement. Sans cela, 20 éléments sont repeints.

..bien entendu cela dépend du projet et si vous avez besoin de l'une des fonctionnalités que j'ai mentionnées. Google utilise des éléments survolés pour Gmail pour utiliser la fonctionnalité décrite en a). Je pense que cela en vaut la peine, même compte tenu de la petite taille des anciens iphones (372 pixels comme vous l’avez dit).

1
scooterlord

Il est possible d’obtenir une application Web fonctionnant en plein écran sous iOS et Android, elle s’appelle un PWA et après le travail acharné de mucha, c’était le seul moyen de résoudre ce problème.

Les PWA ouvrent un certain nombre d’options de développement intéressantes à ne pas manquer. J'en ai déjà fait quelques-unes, consultez ce Manuel d'appels d'offres publics et privés pour les concepteurs (en espagnol). Et voici une explication anglaise du site CosmicJS

0
ganar