Personnaliser les commandes de fenêtre en superposition de la barre de titre de votre PWA

Utilisez la zone de la barre de titre à côté des commandes de la fenêtre pour que votre PWA ressemble davantage à une application.

Vous vous souvenez peut-être de mon article intitulé Adapter votre PWA à votre application. comment j'ai mentionné la personnalisation de la barre de titre de votre application en tant que pour créer une expérience plus proche de celle des applications. Voici un exemple de ce à quoi cela peut ressembler affichant l'application macOS Podcasts.

<ph type="x-smartling-placeholder">
</ph> Barre de titre de l&#39;application macOS Podcasts affichant les boutons de commandes multimédias et les métadonnées du podcast en cours de lecture. <ph type="x-smartling-placeholder">
</ph> Avec une barre de titre personnalisée, votre PWA ressemble davantage à une application spécifique à une plate-forme.
.

Vous pourriez être tenté de vous opposer en affirmant que Podcasts est une application macOS spécifique à la plate-forme qui ne s'exécutent pas dans un navigateur et peuvent donc faire ce qu'il veut sans avoir à passer en revue des règles de pare-feu. C'est vrai, mais la bonne nouvelle, c'est que la fonctionnalité Superposition des commandes de fenêtre, cet article vous permettra bientôt de créer des interfaces utilisateur similaires pour votre PWA.

Composants de superposition des commandes de fenêtre

La superposition des commandes de fenêtre comprend quatre sous-fonctionnalités:

  1. La valeur "window-controls-overlay" du champ "display_override" dans le fichier manifeste de l'application Web.
  2. Les variables d'environnement CSS titlebar-area-x, titlebar-area-y, titlebar-area-width et titlebar-area-height
  3. La standardisation de la propriété CSS -webkit-app-region, qui était auparavant propriétaire, en tant que app-region pour définir des régions déplaçables dans le contenu Web.
  4. Un mécanisme permettant d'interroger et de contourner la région des commandes de fenêtre via la windowControlsOverlay membre de window.navigator.

Qu'est-ce que la superposition des commandes de fenêtre ?

La zone de la barre de titre correspond à l'espace situé à gauche ou à droite des commandes de la fenêtre (c'est-à-dire, pour réduire, agrandir, fermer, etc.) et contient souvent le titre de l'application. Fenêtre La superposition des commandes permet aux progressive web apps (PWA) de donner un aspect plus proche de celui des applications en permutant la barre de titre pleine largeur existante pour une petite superposition contenant les commandes de la fenêtre. Cela permet aux développeurs de placer du contenu personnalisé dans la zone qui était auparavant contrôlée par le navigateur.

État actuel

Étape État
1. Créer une vidéo explicative Fin
2. Créer l'ébauche initiale de la spécification Fin
3. Recueillir des commentaires et itérer sur la conception En cours
4. Phase d'évaluation Terminé
5. Lancement Terminée (dans Chromium 104)

Utiliser la superposition des commandes de fenêtre

Ajouter window-controls-overlay au fichier manifeste de l'application Web

Une progressive web app peut activer la superposition des commandes des fenêtres en ajoutant "window-controls-overlay" en tant que membre principal "display_override" dans le fichier manifeste de l'application Web:

{
  "display_override": ["window-controls-overlay"]
}

La superposition des commandes de fenêtre n'est visible que lorsque toutes les conditions suivantes sont remplies:

  1. L'application n'est pas ouverte dans le navigateur, mais dans une fenêtre PWA distincte.
  2. Le fichier manifeste inclut "display_override": ["window-controls-overlay"]. (Les autres valeurs sont autorisé par la suite.)
  3. La PWA s'exécute sur un système d'exploitation de bureau.
  4. L'origine actuelle correspond à l'origine pour laquelle la PWA a été installée.

Le résultat est une zone vide dans la barre de titre, avec les commandes de fenêtre habituelles à gauche ou l'icône selon le système d'exploitation.

<ph type="x-smartling-placeholder">
</ph> Fenêtre d&#39;application avec une barre de titre vide et les commandes des fenêtres sur la gauche. <ph type="x-smartling-placeholder">
</ph> Barre de titre vide prête pour le contenu personnalisé.

Déplacer du contenu dans la barre de titre

Maintenant que vous avez de la place dans la barre de titre, vous pouvez y déplacer un élément. Pour cet article, je créé une PWA de contenu sélectionné Wikimedia. Une fonction utile pour cette application peut être une recherche de mots dans les titres des articles. Le code HTML de la fonctionnalité de recherche se présente comme suit:

<div class="search">
  <img src="logo.svg" alt="Wikimedia logo." width="32" height="32" />
  <label>
    <input type="search" />
    Search for words in articles
  </label>
</div>

Pour déplacer div vers le haut dans la barre de titre, du code CSS est nécessaire:

.search {
  /* Make sure the `div` stays there, even when scrolling. */
  position: fixed;
  /**
   * Gradient, because why not. Endless opportunities.
   * The gradient ends in `#36c`, which happens to be the app's
   * `<meta name="theme-color" content="#36c">`.
   */
  background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
  /* Use the environment variable for the left anchoring with a fallback. */
  left: env(titlebar-area-x, 0);
  /* Use the environment variable for the top anchoring with a fallback. */
  top: env(titlebar-area-y, 0);
  /* Use the environment variable for setting the width with a fallback. */
  width: env(titlebar-area-width, 100%);
  /* Use the environment variable for setting the height with a fallback. */
  height: env(titlebar-area-height, 33px);
}

Vous pouvez voir l'effet de ce code dans la capture d'écran ci-dessous. La barre de titre est entièrement réactive. Quand ? lorsque vous redimensionnez la fenêtre de la PWA, la barre de titre réagit comme si elle était composée d'un contenu HTML standard. ce qui, en fait, l'est.

<ph type="x-smartling-placeholder">
</ph> Fenêtre d&#39;application avec une barre de recherche dans la barre de titre. <ph type="x-smartling-placeholder">
</ph> La nouvelle barre de titre est active et responsive.

Déterminer quelles parties de la barre de titre sont déplaçables

Même si la capture d'écran ci-dessus suggère que vous avez terminé, ce n'est pas tout à fait terminé. La fenêtre PWA est n'est plus déplaçable (à l'exception d'une très petite zone), car les boutons des commandes de fenêtre ne sont pas et le reste de la barre de titre est le widget Recherche. Corrigez ce problème avec la propriété CSS app-region avec la valeur drag ; Dans le cas concret, il est acceptable de faire Tout ce qui est déplaçable à l'exception de l'élément input

/* The entire search `div` is draggable… */
.search {
  -webkit-app-region: drag;
  app-region: drag;
}

/* …except for the `input`. */
input {
  -webkit-app-region: no-drag;
  app-region: no-drag;
}

Une fois ce CSS en place, l'utilisateur peut faire glisser la fenêtre de l'application comme d'habitude en faisant glisser les éléments div, img, ou label. Seul l'élément input est interactif. Il est donc possible de saisir la requête de recherche.

Détection de caractéristiques

La prise en charge de la superposition des commandes de fenêtre peut être détectée en testant l'existence windowControlsOverlay:

if ('windowControlsOverlay' in navigator) {
  // Window Controls Overlay is supported.
}

Interroger la région des commandes de fenêtre avec windowControlsOverlay

Jusqu'à présent, le code présente un problème: sur certaines plates-formes, les commandes des fenêtres se trouvent à droite, sur d'autres à gauche. Pour ne rien arranger, les "trois points" Le menu Chrome va changer en fonction de la plate-forme. Cela signifie que l'image de fond en dégradé linéaire doit être adapté dynamiquement pour s'exécuter depuis #131313maroon ou maroon#131313maroon, de sorte qu'il se fond dans la couleur d'arrière-plan maroon de la barre de titre déterminée par <meta name="theme-color" content="maroon"> Pour ce faire, vous pouvez interroger API getTitlebarAreaRect() sur la propriété navigator.windowControlsOverlay.

if ('windowControlsOverlay' in navigator) {
  const { x } = navigator.windowControlsOverlay.getTitlebarAreaRect();
  // Window controls are on the right (like on Windows).
  // Chrome menu is left of the window controls.
  // [ windowControlsOverlay___________________ […] [_] [■] [X] ]
  if (x === 0) {
    div.classList.add('search-controls-right');
  }
  // Window controls are on the left (like on macOS).
  // Chrome menu is right of the window controls overlay.
  // [ [X] [_] [■] ___________________windowControlsOverlay [⋮] ]
  else {
    div.classList.add('search-controls-left');
  }
} else {
  // When running in a non-supporting browser tab.
  div.classList.add('search-controls-right');
}

Au lieu d'inclure directement l'image de fond dans les règles CSS de la classe .search (comme précédemment), le code modifié utilise désormais deux classes que le code ci-dessus définit dynamiquement.

/* For macOS: */
.search-controls-left {
  background-image: linear-gradient(90deg, #36c, 45%, #131313, 90%, #36c);
}

/* For Windows: */
.search-controls-right {
  background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
}

Déterminer si la superposition des commandes des fenêtres est visible

La superposition des commandes de fenêtre n'est pas toujours visible dans la zone de la barre de titre. Bien qu'il n'est pas disponible dans les navigateurs qui n'acceptent pas la fonctionnalité de superposition des commandes de fenêtre. ne sera pas non plus visible lorsque la PWA en question s'exécutera dans un onglet. Pour détecter cette situation, vous pouvez interrogez la propriété visible de windowControlsOverlay:

if (navigator.windowControlsOverlay.visible) {
  // The window controls overlay is visible in the title bar area.
}

Vous pouvez également utiliser la requête média display-mode en JavaScript et/ou CSS:

// Create the query list.
const mediaQueryList = window.matchMedia('(display-mode: window-controls-overlay)');

// Define a callback function for the event listener.
function handleDisplayModeChange(mql) {
  // React on display mode changes.
}

// Run the display mode change handler once.
handleDisplayChange(mediaQueryList);

// Add the callback function as a listener to the query list.
mediaQueryList.addEventListener('change', handleDisplayModeChange);
@media (display-mode: window-controls-overlay) { 
  /* React on display mode changes. */ 
}

Être informé des modifications de géométrie

Interroger la zone de superposition des commandes des fenêtres avec getTitlebarAreaRect() peut suffire pour une opération ponctuelle comme définir la bonne image d'arrière-plan en fonction de l'emplacement des commandes des fenêtres, mais dans dans d'autres cas, un contrôle plus précis est nécessaire. Par exemple, un cas d'utilisation possible pourrait être adapter la superposition des commandes de fenêtre en fonction de l'espace disponible et ajouter une blague directement dans la fenêtre de contrôle de la superposition lorsque l'espace est suffisant.

<ph type="x-smartling-placeholder">
</ph> Zone des commandes de fenêtre superposée sur une fenêtre étroite avec un texte abrégé. <ph type="x-smartling-placeholder">
</ph> Commandes de la barre de titre adaptées à une fenêtre étroite.

Pour être informé des modifications apportées aux géométries, vous pouvez vous abonner à navigator.windowControlsOverlay.ongeometrychange ou en configurant un écouteur d'événements pour geometrychange. Cet événement ne se déclenche que lorsque la superposition des commandes de fenêtre est visible, est, lorsque navigator.windowControlsOverlay.visible est true.

const debounce = (func, wait) => {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};

if ('windowControlsOverlay' in navigator) {
  navigator.windowControlsOverlay.ongeometrychange = debounce((e) => {
    span.hidden = e.titlebarAreaRect.width < 800;
  }, 250);
}

Plutôt que d'attribuer une fonction à ongeometrychange, vous pouvez également ajouter un écouteur d'événements à windowControlsOverlay comme indiqué ci-dessous. Pour en savoir plus sur la différence entre les deux, consultez MDN

navigator.windowControlsOverlay.addEventListener(
  'geometrychange',
  debounce((e) => {
    span.hidden = e.titlebarAreaRect.width < 800;
  }, 250),
);

Compatibilité lors de l'exécution dans un onglet et sur des navigateurs non compatibles

Il existe deux cas de figure possibles:

  • Une application s'exécute dans un navigateur compatible avec la superposition des commandes de fenêtre, où l'application est utilisée dans un onglet du navigateur.
  • Une application s'exécute dans un navigateur qui n'est pas compatible avec la superposition des commandes de fenêtre.

Dans les deux cas, le code HTML créé par défaut pour les commandes de la fenêtre la superposition s'affiche de la même manière que le contenu HTML standard et les variables env(). valeurs de remplacement pour le positionnement. Sur les navigateurs compatibles, vous pouvez également décider de ne pas afficher Code HTML désigné pour la superposition des commandes de fenêtre en vérifiant la propriété visible de la superposition et, si il signale false, puis le contenu HTML est masqué.

<ph type="x-smartling-placeholder">
</ph> PWA exécutée dans un onglet de navigateur avec la superposition des commandes de fenêtre affichée dans le corps. <ph type="x-smartling-placeholder">
</ph> Dans les navigateurs plus anciens, les commandes destinées à la barre de titre peuvent facilement s'afficher dans le corps.

Pour rappel, les navigateurs non compatibles ne prennent pas en compte "display_override" du fichier manifeste de l'application Web, ou ne reconnaissez pas la "window-controls-overlay" et ainsi utiliser la prochaine valeur possible selon la chaîne de remplacement, (par exemple, "standalone").

<ph type="x-smartling-placeholder">
</ph> Une PWA s&#39;exécutant en mode autonome avec la superposition des commandes de fenêtre affichée dans le corps. <ph type="x-smartling-placeholder">
</ph> Dans les navigateurs plus anciens, les commandes destinées à la barre de titre peuvent facilement s'afficher dans le corps.

Considérations relatives à l'interface utilisateur

Bien qu'il puisse être tentant, il n'est pas recommandé de créer un menu déroulant classique dans la zone Superposition des commandes des fenêtres. Cela constituerait une violation du consignes de conception sous macOS, une plateforme sur laquelle les utilisateurs s'attendent à des barres de menu (fournies par le système et personnalisées) en haut de l'écran.

Si votre application propose une expérience en plein écran, demandez-vous s'il est judicieux ou non pour que la superposition des commandes de fenêtre soit affichée en plein écran. Vous pourriez peut-être pour réorganiser votre mise en page onfullscreenchange se déclenche automatiquement.

Démo

J'ai créé une démonstration avec laquelle vous pouvez jouer dans différents navigateurs pris en charge et non compatibles, qu’ils soient installés ou non. Pour l'expérience réelle de superposition des commandes de fenêtre, vous devez installer l'application. Vous trouverez ci-dessous deux captures d'écran illustrant ce qui vous attend. La code source de l'application est disponible sur Glitch.

<ph type="x-smartling-placeholder">
</ph> Application de démonstration du contenu sélectionné Wikimedia avec superposition des commandes de fenêtre. <ph type="x-smartling-placeholder">
</ph> L'application de démonstration est disponible pour effectuer des tests.

La fonctionnalité de recherche dans la superposition des commandes de fenêtre est entièrement fonctionnelle:

<ph type="x-smartling-placeholder">
</ph> Application de démonstration Wikimedia Featured Content avec une superposition des commandes de fenêtre et une recherche active sur le terme &quot;cleopa...&quot; mettant en surbrillance l&#39;un des articles
avec le terme &quot;Cléopâtre&quot;. <ph type="x-smartling-placeholder">
</ph> Fonction de recherche utilisant la superposition des commandes de fenêtre

Considérations de sécurité

L'équipe Chromium a conçu et implémenté l'API Window Controls Overlay en suivant les principes fondamentaux définies dans la section Contrôler l'accès à des fonctionnalités puissantes de plate-forme Web, y compris les règles le contrôle, la transparence et l'ergonomie.

Spoofing

Donner aux sites un contrôle partiel sur la barre de titre permet aux développeurs de simuler du contenu était auparavant une région fiable contrôlée par le navigateur. Actuellement, dans les navigateurs Chromium, la version autonome comprend une barre de titre qui, au lancement initial, affiche le titre de la page Web sur la gauche. L'origine de la page à droite, suivie du bouton "Paramètres et plus" et de la fenêtre de contrôle). Après quelques secondes, le texte d'origine disparaît. Si le navigateur est configuré pour lire les messages de droite à gauche (RTL), cette mise en page est inversée de sorte que le texte d'origine se trouve à gauche. Vous accédez ainsi les commandes de fenêtre se superposent pour simuler l'origine si la marge intérieure est insuffisante entre l'origine et le bord droit de la superposition. Par exemple, l'origine "evil.ltd" pourrait être associée à une site "google.com", ce qui laisse croire aux utilisateurs que la source est fiable. L'objectif est de maintenir afin que les utilisateurs sachent quelle est l'origine de l'application et qu'elles correspondent à leurs à vos attentes. Pour les navigateurs configurés de droite à gauche, il doit y avoir suffisamment de marge intérieure à droite de l'origine pour empêcher un site Web malveillant d'ajouter l'origine non sécurisée à une origine approuvée.

Empreintes

L'activation de la superposition des commandes de fenêtre et des régions déplaçables ne pose pas des problèmes de confidentialité considérables en dehors de la détection de fonctionnalités. Toutefois, en raison de des tailles et des positions différentes des boutons de commande de fenêtre en fonction des opérations systèmes, les navigator.windowControlsOverlay.getTitlebarAreaRect() renvoie un objet DOMRect dont la position et les dimensions révèlent des informations sur le système d'exploitation que le navigateur exécute. Actuellement, les développeurs peuvent déjà découvrir le système d'exploitation de la chaîne user-agent. Toutefois, en raison de problèmes de fingerprinting, discussion sur le gel de la chaîne UA et l’unification des versions du système d’exploitation. Il existe un des efforts continus au sein de la communauté des navigateurs pour comprendre à quelle fréquence la taille de la superposition des commandes de fenêtre change d'une plateforme à l'autre, car la version actuelle est qu'elles sont assez stables d'une version à l'autre être utile pour observer les versions mineures du système d’exploitation. Bien qu'il s'agisse d'un d'empreinte numérique, il ne s'applique qu'aux PWA installées qui utilisent le barre de titre et ne s'applique pas à l'utilisation générale du navigateur. De plus, le L'API navigator.windowControlsOverlay ne sera pas disponible pour iFrame intégrés à une PWA.

Si vous accédez à une autre origine dans une PWA, elle reviendra à la version autonome normale la barre de titre, même si elle répond aux critères ci-dessus et s'ouvre avec la superposition des commandes de fenêtre. Cela permet de s'adapter à la barre noire qui apparaît lors de la navigation vers une autre origine. Après revenons à l'origine d'origine, la superposition des commandes des fenêtres est à nouveau utilisée.

<ph type="x-smartling-placeholder">
</ph> Une barre d&#39;URL noire pour la navigation hors d&#39;origine <ph type="x-smartling-placeholder">
</ph> Une barre noire s'affiche lorsque l'utilisateur accède à une autre origine.

Commentaires

L'équipe Chromium souhaite connaître votre avis sur votre expérience avec l'API Window Controls Overlay.

Présentez-nous la conception de l'API

Y a-t-il un aspect de l'API qui ne fonctionne pas comme prévu ? Ou manque-t-il des méthodes ou les propriétés dont vous avez besoin pour mettre en œuvre votre idée ? Vous avez une question ou un commentaire sur la sécurité ? Signalez un problème de spécification dans le dépôt GitHub correspondant ou ajoutez vos commentaires à un problème existant.

Signaler un problème d'implémentation

Avez-vous détecté un bug dans l'implémentation de Chromium ? Ou l'implémentation est-elle différente des spécifications ? Signalez un bug sur new.crbug.com. Veillez à inclure autant de détails que possible, des instructions simples pour reproduire le problème, puis saisissez UI>Browser>WebAppInstalls dans le champ Composants. . Glitch est idéal pour partager des répétitions rapidement et facilement.

Apportez votre soutien à l'API

Prévoyez-vous d'utiliser l'API Window Controls Overlay ? Votre assistance publique aide l'équipe Chromium pour hiérarchiser les fonctionnalités et montre aux autres fournisseurs de navigateurs à quel point il est essentiel de les prendre en charge.

Envoyez un tweet à @ChromiumDev en indiquant le #WindowControlsOverlay et indiquez-nous où et comment vous l'utilisez.

Liens utiles

Remerciements

La superposition des commandes de fenêtre a été implémentée et spécifiée par Amanda Baker, de l'équipe Microsoft Edge. Cet article a été lu par Joe Medley et Kenneth Rohde Christiansen. Image héros de Sigmund sur Unsplash.