web-dev-qa-db-fra.com

Détection du "encoche" de l'appareil mobile

Avec le lancement imminent de l'iPhone X, j'essaie de prendre une longueur d'avance sur le jeu et de préparer certaines de mes applications Web pour gérer tous les changements de conception, le plus important étant le nouveau "cran" qui abrite la caméra avant.

Je me demandais s'il existait ou risquait de trouver un moyen de détecter cela en Javascript.

Fait intéressant, Chris Coyier a écrit un article sur Le "Notch" et le CSS qui m'a amené à découvrir la constante safe-area-inset-right. Existe-t-il un moyen d’y accéder en Javascript et s’agit-il d’un test fiable?.

if (window.constant.safeAreaInsetRight) {
  var notch = true;
}
11
kinggs

Cela pourrait être un peu hacky cependant, en obtenant les hauteurs et les largeurs disponibles de l’écran et en les faisant correspondre à ces spécifications, nous pourrions déterminer s’il s’agissait d’un iPhone X. 

Notez s'il vous plaît

En orientation portrait, la largeur de l'affichage sur l'iPhone X correspond à la largeur des écrans 4.7 "de l'iPhone 6, iPhone 7 et iPhone 8 . L'écran de l'iPhone X est toutefois 145 pt plus grand qu'un 4.7" afficher...

 enter image description here

Donc, d’une part, vous voulez vérifier s’il s’agit d’un iPhone via l’agent utilisateur, d’autre part, vous devez vérifier la zone de l’écran réel (à l’exclusion de l’orientation par défaut de portrait), enfin, une fois que nous savons que c’est un iPhoneX via son écran dimensions que vous pouvez déterminer l'orientation (d'après le tableau sous le diagramme iPhone X ci-dessus)

if (navigator.userAgent.match(/(iPhone)/)){
  if((screen.availHeight == 812) && (screen.availWidth == 375)){

    if((window.innerHeight == "375") && (window.innerWidth == "812")){
      // iPhone X Landscape

    }else{
      // iPhone X Portrait
    }
  }
}

Références: 

avilHeight

avilWidth

Spécifications iPhoneX

En ce qui concerne la solution CSS, j’ai trouvé un article intéressant à ce sujet hier qui pourrait être utile

Supposons que vous avez une barre d’en-tête à position fixe et votre CSS pour iOS 10 ressemble actuellement à ceci:

header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 44px;

    padding-top: 20px; /* Status bar height */
}

Pour que cela s’ajuste automatiquement à iPhone X et aux autres iOS 11 périphériques, vous ajouteriez une option viewport-fit = cover à votre viewport balise méta, et changer le CSS pour référencer la constante:

header {
    /* ... */

    /* Status bar height on iOS 10 */
    padding-top: 20px;

    /* Status bar height on iOS 11+ */
    padding-top: constant(safe-area-inset-top);
}

Il est important de conserver la valeur de repli pour les appareils plus anciens qui vous ne saurez pas comment interpréter la syntaxe constant (). Vous pouvez aussi utiliser constantes dans les expressions CSS calc ().

Article

6
Adriani6
// iphone X detection

function hasNotch() {
    if (CSS.supports('padding-bottom: env(safe-area-inset-bottom)')) {
      let div = document.createElement('div');
      div.style.paddingBottom = 'env(safe-area-inset-bottom)';
      document.body.appendChild(div);
      let calculatedPadding = parseInt(window.getComputedStyle(div).paddingBottom, 10);
      document.body.removeChild(div);
      if (calculatedPadding > 0) {
        return true;
      }
    }
    return false;
  }
4
Youssef Makboul

Depuis la réponse de @ youssef-makboul et commentée par @hjellek, iOS a changé de syntaxe de constante () à env () et un repli est nécessaire pour prendre en charge cette approche sur toutes les versions actuelles d'iPhone X iOS.

const hasNotch = function () {
    var proceed = false;
    var div = document.createElement('div');
    if (CSS.supports('padding-bottom: env(safe-area-inset-bottom)')) {
        div.style.paddingBottom = 'env(safe-area-inset-bottom)';
        proceed = true;
    } else if (CSS.supports('padding-bottom: constant(safe-area-inset-bottom)')) {
        div.style.paddingBottom = 'constant(safe-area-inset-bottom)';
        proceed = true;
    }
    if (proceed) {
        document.body.appendChild(div);
        let calculatedPadding = parseInt(window.getComputedStyle(div).paddingBottom);
        document.body.removeChild(div);
        if (calculatedPadding > 0) {
            return true;
        }
    }
    return false;
};
2
Robert Waddell

Quelques choses à ajouter: 

Assurez-vous que vous avez les éléments suivants dans votre index.html

<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

Aditionellement: 

Excellent article à ce sujet ici: CSS Tricks Notch

0
Tsavo Knott