2 points par GN⁺ 2024-05-11 | 1 commentaires | Partager sur WhatsApp
  • Il est possible de créer une interface de popover qui s’affiche au-dessus de la page en s’appuyant uniquement sur les fonctionnalités natives du navigateur, ce qui permet d’implémenter de façon plus cohérente des motifs comme les menus, suggestions et notifications
  • Les popovers de la Popover API sont toujours non modaux ; pour une interface qui doit bloquer les interactions avec la page, `` est plus adapté
  • Les bascules simples se gèrent avec des attributs HTML comme popover, popovertarget et popovertargetaction, et, si besoin, des méthodes JavaScript permettent de contrôler l’état d’affichage
  • ::backdrop, :popover-open, beforetoggle, toggle, etc. permettent de gérer le style et les changements d’état, tandis que les interest invokers prennent en charge l’affichage au survol/au focus sans JavaScript
  • C’est une fonctionnalité Baseline 2025 disponible sur les appareils et navigateurs récents depuis janvier 2025, mais il faut vérifier la compatibilité avec les environnements plus anciens ou certaines fonctionnalités de détail

Le problème que résout la Popover API

  • La Popover API fournit un mécanisme standard pour afficher du contenu de type popover au-dessus du reste du contenu d’une page
  • Les popovers peuvent être contrôlés uniquement avec des attributs HTML, ou bien leur état affiché/masqué peut être géré directement via une API JavaScript
  • Des motifs d’interface autrefois désignés sur le Web comme overlays, popups, popovers ou dialogs peuvent ainsi être implémentés de façon plus cohérente grâce aux fonctionnalités natives du navigateur

Si vous avez besoin d’un modal, utilisez ``

  • Les interfaces de type popover se divisent globalement en deux catégories : modales et non modales
    • En mode modal, il est impossible d’interagir avec le reste de la page tant que le popover est affiché
    • En mode non modal, on peut continuer à interagir avec le reste de la page même si le popover est ouvert
  • Les popovers créés avec la Popover API sont toujours non modaux
  • Si vous avez besoin d’un popover modal qui bloque les interactions avec la page, l’élément `` est approprié
  • Une approche consistant à appliquer popover à reste aussi valide, comme avec : elle permet d’utiliser à la fois le contrôle du popover et la sémantique de dialog

Utilisation de base

  • La Popover API peut être souvent utilisée pour des interfaces nécessitant une interaction utilisateur
    • Menus d’action
    • Notifications toast personnalisées
    • Suggestions pour éléments de formulaire
    • Sélecteurs de contenu
    • Interfaces pédagogiques
  • Il est possible de créer un simple bouton de bascule de popover uniquement en HTML
Toggle the popover
Popover content

  • En JavaScript, HTMLElement.togglePopover() permet de basculer l’état affiché/masqué d’un popover
  • L’API fournit aussi des événements pour réagir aux changements d’état du popover ainsi que des fonctionnalités CSS facilitant son style

Attributs HTML

  • interestfor
    • Définit un élément HTML , ou , ou un élément SVG comme interest invoker
    • La valeur correspond à l’id de l’élément cible ; lorsque l’intérêt apparaît ou disparaît sur l’élément invoker, l’élément cible est affecté
  • popover
    • Attribut global qui transforme un élément en élément popover
    • Peut prendre les états "auto", "hint" et "manual"
  • popovertarget
    • Transforme un élément ou en bouton de contrôle de popover
    • La valeur est l’ID de l’élément popover à contrôler
  • popovertargetaction
    • Définit l’action que le bouton de contrôle doit exécuter sur le popover
    • Les valeurs possibles sont "hide", "show" et "toggle"

Gérer l’état d’affichage avec CSS

  • ::backdrop
    • Pseudo-élément plein écran placé juste derrière l’élément popover
    • Il peut servir, si nécessaire, à appliquer des effets comme un flou au contenu de la page derrière le popover
  • interest-delay, interest-delay-start, interest-delay-end
    • Ajoutent un délai entre le moment où l’utilisateur manifeste ou perd son intérêt, et celui où le navigateur réagit
  • :interest-source, :interest-target
    • Permettent d’appliquer respectivement des styles à l’invoker et à l’élément cible lié lorsque l’intérêt est affiché
  • :popover-open
    • Pseudo-classe qui ne correspond qu’à un élément popover lorsqu’il est affiché
    • Sert à styliser un popover dans son état ouvert

Interface JavaScript et extensions DOM

  • InterestEvent
    • Objet d’événement pour les événements interest et loseinterest
    • Inclut une propriété source contenant une référence à l’élément interest invoker associé
  • ToggleEvent
    • Représente l’événement déclenché lorsqu’un élément popover passe de l’état affiché à masqué, ou inversement
    • C’est l’objet d’événement utilisé pour beforetoggle et toggle
  • interestForElement
    • Permet d’obtenir ou de définir une référence vers l’élément ciblé par un interest invoker
    • Disponible sur HTMLButtonElement, HTMLAnchorElement, HTMLAreaElement et SVGAElement
  • HTMLElement.popover
    • Permet d’obtenir ou de définir en JavaScript l’état popover d’un élément
    • Utilise les valeurs "auto", "hint" et "manual", et peut aussi servir à la détection de fonctionnalité
    • Reflète la valeur de l’attribut global HTML popover
  • popoverTargetElement
    • Permet, sur HTMLButtonElement et HTMLInputElement, d’obtenir ou de définir l’élément popover contrôlé par le bouton
    • C’est le pendant JavaScript de l’attribut HTML popovertarget
  • popoverTargetAction
    • Permet, sur HTMLButtonElement et HTMLInputElement, d’obtenir ou de définir l’action popover à exécuter
    • Utilise les valeurs "hide", "show" et "toggle", et reflète l’attribut popovertargetaction

Méthodes et événements

  • HTMLElement.hidePopover()
    • Retire l’élément popover de la top layer et le masque en lui appliquant display: none
  • HTMLElement.showPopover()
    • Ajoute l’élément popover à la top layer pour l’afficher
  • HTMLElement.togglePopover()
    • Fait basculer l’élément popover entre les états affiché et masqué
  • beforetoggle
    • Se déclenche juste avant que l’état du popover ne passe de visible à masqué, ou l’inverse
    • Peut être utilisé pour empêcher l’ouverture du popover, ou pour mettre à jour d’autres éléments selon son état
  • toggle
    • Se déclenche juste après le changement d’état du popover
  • interest
    • Se déclenche sur l’élément cible d’un interest invoker lorsque l’intérêt est affiché
  • loseinterest
    • Se déclenche sur l’élément cible d’un interest invoker lorsque l’intérêt disparaît

Exemples et liens vers les spécifications

1 commentaires

 
GN⁺ 2024-05-11
Avis Hacker News
  • L’API Popover semble pouvoir vraiment changer la donne une fois que le positionnement d’ancre CSS (CSS Anchor Positioning) sera disponible
    Le positionnement d’ancre permet de placer un élément par rapport à un autre élément de la page
    Combiné à l’API Popover, cela permet d’implémenter de façon déclarative des infobulles personnalisées ou des menus contextuels, sans avoir besoin de bibliothèques comme PopperJS
    https://developer.chrome.com/blog/tether-elements-to-each-ot...
    https://popper.js.org/docs/v2/

    • Je viens justement de publier un nouvel article sur l’utilisation de l’API d’ancre CSS, et elle devrait arriver dans Chromium la semaine prochaine
      https://developer.chrome.com/blog/anchor-positioning-api
    • L’état du support navigateur est visible ici
      https://caniuse.com/css-anchor-positioning
    • Si le positionnement d’ancre CSS avait existé ces dernières années, cela m’aurait fait gagner un temps fou
    • C’est la pièce maîtresse qui manquait
      J’ai essayé la semaine dernière de créer puis de déployer quelque chose avec la nouvelle API Popover, mais les limitations du support du positionnement dans les navigateurs ont fortement réduit les cas d’usage possibles
      Même Firefox, le dernier navigateur à manquer à l’appel, semble déjà avoir ajouté le positionnement d’ancre en bêta, donc cela ne devrait plus prendre très longtemps
    • C’est surprenant qu’en 2024, HTML/CSS n’ait toujours pas d’attribut d’infobulle comme title
  • Si vous avez besoin d’une boîte de dialogue modale, il y a aussi l’élément <dialog>
    https://developer.mozilla.org/en-US/docs/Web/HTML/Element/di...

    • Si vous avez besoin de contenu dépliable/repliable, ou même, en forçant un peu, d’un « menu déroulant », vous pouvez aussi utiliser <details>
      Étrangement, contrairement à <dialog> ou <details>, <popover> ne semble pas pouvoir être mis déclarativement à l’état open via un simple attribut
      Cela donne l’impression d’une fonctionnalité manquante, et j’espère qu’il y avait une raison derrière cette décision
      https://developer.mozilla.org/en-US/docs/Web/HTML/Element/de...
    • Je préfère prévenir que, pour amener les animations et le comportement modal général au niveau d’exigence attendu aujourd’hui, il faut quand même pas mal de travail
      C’est tout à fait faisable, mais ce n’est en rien une tâche anodine
    • Comme cela a été signalé, les animations sont plus compliquées, mais il y a l’accessibilité, la fermeture avec la touche Échap, un fond intégré et un piège de focus intégré
      Le support de Safari a pris du temps, mais c’est désormais utilisable partout
      Cela me paraît préférable à assembler soi-même différents tags
    • C’est déjà abordé dans les premiers paragraphes de l’article
  • Si cette fonctionnalité était implémentée en collaboration avec le système de fenêtres de l’OS hôte, elle semblerait clairement nécessaire
    À l’heure actuelle, les popovers doivent toujours être simulés d’une manière qui ne fonctionne pas toujours bien
    Par exemple, le <select> natif du navigateur peut s’étendre au-delà des limites de la fenêtre du navigateur sans risquer d’être coupé, alors qu’un faux select sophistiqué d’un toolkit comme Quasar ne le peut pas, ce qui limite les options de placement
    Pour bien faire les choses, sous win32 chaque popover devrait probablement avoir son propre HWND, et sous Cocoa/macOS être contenu dans sa propre NSView
    Je me demande si les navigateurs implémentent réellement cela ainsi, ou s’ils se contentent simplement de dessiner par-dessus à l’intérieur de la fenêtre du navigateur

    • Ces popovers ne sont en fait que de simples nœuds DOM, stylés avec du CSS classique
      Si l’on autorisait un site web à dessiner en dehors du viewport défini, il deviendrait beaucoup plus facile d’imiter de manière crédible des boîtes de dialogue du navigateur ou du système d’exploitation, en dehors de cas extrêmement limités comme alert(), confirm() ou [title]
      Une page pourrait par exemple imiter le widget de déverrouillage d’une extension de gestionnaire de mots de passe
      C’est un risque de sécurité majeur, qui ne me semble pas valoir les bénéfices limités que cela apporterait
      Ce n’est pas une inquiétude théorique
      Des escrocs créent depuis des années des interfaces factices très convaincantes, y compris de fausses fenêtres popup imitant jusqu’au chrome du navigateur, parfois même déplaçables par glisser-déposer
      Le fait de ne pas pouvoir dessiner en dehors des limites du viewport était quasiment la seule contrainte qu’ils n’avaient pas réussi à contourner
    • Je ne sais pas à quel point une telle fonctionnalité serait réellement utile
      Sur les petits appareils, le navigateur web occupe presque toujours tout l’écran, et même sur les grands moniteurs il touche généralement au moins un coin
    • Sémantiquement, cela semblerait aussi plus facile à détecter
      C’est utile pour l’accessibilité, l’exploration par les robots, ou même si quelqu’un veut créer un plugin « anti-popup »
    • Firefox prend techniquement en charge la possibilité de faire « surgir » une partie du contenu de la page dans une fenêtre au niveau du système d’exploitation distincte
      Cette fonctionnalité est exposée via un élément XUL, utilisable uniquement dans du [X]HTML privilégié rendu par le processus principal du navigateur
      Il est peu probable qu’un développeur de navigateur veuille donner à une page web ordinaire le droit de créer des fenêtres de l’OS sans bordure
    • Il est peu probable que les web apps obtiennent bientôt le genre d’intégration native au système de fenêtres qu’elles semblent imaginer
      Si certains contrôles standard se comportent ainsi, c’est un effet de bord d’implémentations natives propres à chaque OS, et non quelque chose qui doive nécessairement être implémenté de cette façon
  • Les navigateurs ont des bloqueurs de pop-up intégrés, donc le fait de créer une API comme celle-ci est un peu drôle.
    Je sais bien qu’il y a une différence, mais quand même.
    Je suis assez vieux pour me souvenir de la guerre des pop-up/pop-under de la fin des années 1990 et du début des années 2000.
    On dirait que cette bataille a été gagnée, mais la guerre autour de notre attention est encore loin d’être terminée.

    • On dirait que tu compares deux choses différentes.
      Un popover est un élément flottant qui affiche des informations contextuelles quand on en a besoin.
      Ce que tu mentionnes est complètement différent.
    • Je vois l’idée, mais en pratique ça ne me semble pas être une vraie comparaison.
      Les pop-up balancent des fenêtres poubelles au niveau du système d’exploitation et, dans le pire des cas, empêchent carrément d’utiliser l’ordinateur.
      Une boîte de dialogue popover disparaît dès qu’on ferme l’onglet.
      Les popovers de ce style sont assez utiles pour afficher des informations et sont déjà utilisés depuis très longtemps.
      On peut certes en faire un usage agaçant, mais comme les modales, il y a aussi beaucoup de vrais cas d’usage.
    • On voit souvent ce genre de réaction, mais ça n’a pas vraiment de sens.
      On peut déjà implémenter des popovers aujourd’hui avec un simple div, etc.
      Exemple : https://getbootstrap.com/docs/5.3/components/popovers/
      Ce qui change, c’est qu’on peut implémenter des popovers sans bibliothèque additionnelle magique.
      Même si on empêchait l’existence d’un élément explicite « popover », les gens continueraient simplement à utiliser des bibliothèques custom.
    • Ce n’est pas une pop-up.
      Si les gens détestent les pop-up, c’est parce qu’elles sont intrusives et qu’elles ouvrent une fenêtre séparée.
      Cette API remplace les modales en div et fait gagner du temps et du code aux développeurs.
    • À l’origine, les implémentations de pop-up brisaient la frontière entre le contenu de l’application et le système d’exploitation, et les bloqueurs de pop-up étaient là pour empêcher ça.
      Cette API ne brise pas cette frontière.
      Ce serait indésirable, car quand cette frontière disparaît, l’utilisabilité et la sécurité du système se dégradent.
  • On dit que « les popovers créés avec la Popover API sont toujours non modaux. Si vous voulez créer un popover modal, l’élément <dialog> est le bon choix », mais je ne vois pas vraiment pourquoi.
    C’est un cas d’usage tout à fait légitime pour un popover.
    Surtout si l’arrière-plan est flouté quand il est ouvert, et si un bouton flouté peut pousser l’utilisateur à cliquer dessus par erreur, on peut se demander pourquoi offrir cette fonctionnalité.
    En cherchant, j’ai vu qu’on pouvait combiner les deux.
    Quelque chose du genre : « si vous voulez combiner le contrôle des popovers et la sémantique des boîtes de dialogue, vous pouvez transformer un élément <dialog> en popover ».
    Dans ce cas, un attribut comme modal aurait peut-être plus de sens ici.
    Puisqu’on reconnaît clairement qu’il existe un cas d’usage.

    • C’est probablement, entre autres raisons, parce que <dialog> existait bien avant.
  • Très bien.
    Si j’ai bien compris, plutôt que d’introduire une nouvelle fonctionnalité, cela semble surtout simplifier ce qui nécessitait auparavant une div modale, une div de masque, une div conteneur et un CSS de positionnement pénible.
    Il y a aussi de nouvelles pseudo-classes pour faciliter le style, et ça me plaît.

    • Ça permet aussi d’utiliser les fonctionnalités de base sans JavaScript.
      Plus besoin de bricoler avec des cases à cocher cachées.
      Je ne sais pas jusqu’où on peut aller sans JS pour des popovers avec style et animations, mais le support sans JS avec une gestion correcte du focus est une bonne chose.
      J’aimerais aussi dire que le support de l’accessibilité est intégré, mais je ne le trouve pas dans la spécification actuelle.
      Si cela gère aussi l’annonce de l’élément aux outils d’accessibilité comme les lecteurs d’écran, ce serait d’une grande aide.
      Parce que quand on le fait à la main, c’est très facile d’oublier des choses.
    • Cette API permet de contrôler l’état d’affichage d’un élément popover dans le DOM même sans JavaScript.
      C’est clairement utile.
  • Démo : https://mdn.github.io/dom-examples/popover-api

    • Dans la démo des popovers imbriqués, on ne peut pas aller en diagonale de Pizza à Ham.
      C’est parce que personne n’a implémenté de délai avant la disparition du sous-menu, ni dans Chrome ni dans Firefox.
      Des décennies de recherche sur l’expérience utilisateur ont été perdues, presque comme on pouvait s’y attendre.
      https://mdn.github.io/dom-examples/popover-api/nested-popove...
    • Le tableau de compatibilité des navigateurs indique que ça fonctionne, mais ça ne semble pas marcher sur iOS Safari.
  • Ça a l’air sympa, mais je ne comprends pas pourquoi cette page n’a aucune image montrant ce qu’est un popover.

  • Excellent.
    Voici une implémentation custom réalisée avec Stimulus en utilisant Popper.
    https://github.com/tramlinehq/tramline/blob/main/app/javascr...
    Et voici l’implémentation pour les boîtes de dialogue.
    https://github.com/tramlinehq/tramline/blob/main/app/javascr...