2 Punkte von GN⁺ 2024-05-11 | 1 Kommentare | Auf WhatsApp teilen
  • Mit reinen Browser-Bordmitteln lässt sich eine Popover-UI erstellen, die über der Seite erscheint, sodass sich Muster wie Menüs, Vorschläge und Benachrichtigungen konsistenter umsetzen lassen
  • Popovers der Popover API sind immer nicht modal, daher ist `` besser geeignet für UIs, die die Interaktion mit der Seite blockieren müssen
  • Einfache Umschalter lassen sich über HTML-Attribute wie popover, popovertarget und popovertargetaction umsetzen; bei Bedarf kann der Sichtbarkeitsstatus per JavaScript-Methode gesteuert werden
  • Mit ::backdrop, :popover-open, beforetoggle, toggle usw. lassen sich Styling und Statusänderungen behandeln, und interest invokers unterstützen Hover-/Focus-Anzeige ohne JavaScript
  • Es handelt sich um ein Baseline-2025-Feature, das ab Januar 2025 auf aktuellen Geräten und in modernen Browsern funktioniert, aber die Kompatibilität älterer Umgebungen und einzelner Detailfunktionen sollte geprüft werden

Welches Problem die Popover API löst

  • Die Popover API bietet einen standardisierten Mechanismus, um Popover-Inhalte über anderen Seiteninhalten anzuzeigen
  • Popovers können ausschließlich über HTML-Attribute gesteuert oder über die JavaScript-API direkt in ihrem Anzeige-/Ausblendestatus verwaltet werden
  • UI-Muster, die im Web als overlays, popups, popovers oder dialogs bezeichnet wurden, lassen sich damit mit Browser-Bordmitteln konsistenter umsetzen

Wenn ein Modal nötig ist, verwende ``

  • Popover-UIs lassen sich grob in modal und nicht modal einteilen
    • Modal bedeutet, dass während der Anzeige des Popovers keine Interaktion mit dem Rest der Seite möglich ist
    • Nicht modal bedeutet, dass mit dem Rest der Seite weiter interagiert werden kann, auch wenn das Popover sichtbar ist
  • Mit der Popover API erstellte Popovers sind immer nicht modal
  • Wenn ein modales Popover benötigt wird, das die Seiteninteraktion blockiert, ist das ``-Element geeignet
  • Auch ein Ansatz wie mit `popover` auf ist gültig; so lassen sich Popover-Steuerung und Dialog-Semantik gemeinsam nutzen

Grundlegende Verwendung

  • Die Popover API eignet sich häufig für UIs, die Benutzerinteraktion erfordern
    • Aktionsmenüs
    • Benutzerdefinierte Toast-Benachrichtigungen
    • Formularfeld-Vorschläge
    • Inhaltsauswähler
    • Schulungs-UI
  • Mit reinem HTML lässt sich ein einfacher Button zum Umschalten eines Popovers erstellen
Toggle the popover
Popover content

  • In JavaScript schaltet HTMLElement.togglePopover() den Anzeige-/Ausblendestatus des Popovers um
  • Die API bietet außerdem Events für Reaktionen auf Statusänderungen von Popovers sowie CSS-Funktionen zur Unterstützung des Stylings

HTML-Attribute

  • interestfor
    • Definiert HTML-, und -Elemente oder SVG--Elemente als interest invoker
    • Der Wert ist die id des Zielelements; wenn beim Invoker interest erscheint oder verschwindet, wird das Zielelement beeinflusst
  • popover
    • Ein globales Attribut, das ein Element in ein Popover-Element verwandelt
    • Es kann die Zustände "auto", "hint" und "manual" als Wert annehmen
  • popovertarget
    • Macht ein - oder -Element zu einem Button zur Steuerung eines Popovers
    • Der Wert ist die ID des zu steuernden Popover-Elements
  • popovertargetaction
    • Legt fest, welche Aktion der Steuer-Button auf dem Popover ausführt
    • Mögliche Werte sind "hide", "show" und "toggle"

Sichtbarkeitsstatus mit CSS behandeln

  • ::backdrop
    • Ein bildschirmfüllendes Pseudoelement, das direkt hinter dem Popover-Element liegt
    • Bei Bedarf lassen sich damit Effekte wie Unschärfe auf den Seiteninhalt hinter dem Popover anwenden
  • interest-delay, interest-delay-start, interest-delay-end
    • Fügen eine Verzögerung zwischen dem Zeitpunkt hinzu, an dem der Benutzer interest zeigt oder verliert, und dem Zeitpunkt, an dem der Browser reagiert
  • :interest-source, :interest-target
    • Erlauben es, im Zustand mit aktivem interest jeweils Styles auf den Invoker und das verknüpfte Zielelement anzuwenden
  • :popover-open
    • Eine Pseudoklasse, die nur passt, wenn das Popover-Element sichtbar ist
    • Wird verwendet, um das geöffnete Popover zu stylen

JavaScript-Schnittstellen und DOM-Erweiterungen

  • InterestEvent
    • Das Event-Objekt für die Events interest und loseinterest
    • Enthält die Eigenschaft source, die eine Referenz auf das verknüpfte interest-invoker-Element enthält
  • ToggleEvent
    • Repräsentiert das Event, das ausgelöst wird, wenn ein Popover-Element zwischen sichtbar und verborgen wechselt
    • Ist das Event-Objekt für die Events beforetoggle und toggle
  • interestForElement
    • Holt oder setzt die Referenz auf das Element, das ein interest invoker als Ziel verwendet
    • Kann bei HTMLButtonElement, HTMLAnchorElement, HTMLAreaElement und SVGAElement verwendet werden
  • HTMLElement.popover
    • Holt oder setzt den Popover-Status eines Elements per JavaScript
    • Verwendet die Werte "auto", "hint" und "manual" und dient auch der Feature-Erkennung
    • Spiegelt den Wert des globalen HTML-Attributs popover wider
  • popoverTargetElement
    • Holt oder setzt bei HTMLButtonElement und HTMLInputElement das Popover-Element, das vom Steuer-Button gesteuert wird
    • Ist das JavaScript-Gegenstück zum HTML-Attribut popovertarget
  • popoverTargetAction
    • Holt oder setzt bei HTMLButtonElement und HTMLInputElement die auszuführende Popover-Aktion
    • Verwendet die Werte "hide", "show" und "toggle" und spiegelt das Attribut popovertargetaction wider

Methoden und Events

  • HTMLElement.hidePopover()
    • Entfernt das Popover-Element aus der top layer und blendet es aus, indem es mit display: none gestylt wird
  • HTMLElement.showPopover()
    • Fügt das Popover-Element zur top layer hinzu und zeigt es an
  • HTMLElement.togglePopover()
    • Schaltet das Popover-Element zwischen sichtbar und verborgen um
  • beforetoggle
    • Tritt unmittelbar auf, bevor sich der Status des Popover-Elements zwischen sichtbar und verborgen ändert
    • Kann verwendet werden, um das Öffnen des Popovers zu verhindern oder abhängig vom Popover-Status andere Elemente zu aktualisieren
  • toggle
    • Tritt direkt nach der Statusänderung des Popover-Elements auf
  • interest
    • Tritt auf dem Zielelement eines interest invoker auf, wenn interest angezeigt wird
  • loseinterest
    • Tritt auf dem Zielelement eines interest invoker auf, wenn interest verschwindet

Beispiel- und Spezifikationslinks

1 Kommentare

 
GN⁺ 2024-05-11
Hacker-News-Kommentare
  • Die Popover API könnte wirklich ein großer Wendepunkt werden, sobald auch CSS Anchor Positioning dazukommt
    Anchor Positioning erlaubt es, Elemente relativ zu anderen Elementen auf der Seite zu platzieren
    In Kombination mit der Popover API lassen sich benutzerdefinierte Tooltips oder Kontextmenüs deklarativ umsetzen, und Bibliotheken wie PopperJS würden überflüssig
    https://developer.chrome.com/blog/tether-elements-to-each-ot...
    https://popper.js.org/docs/v2/

    • Ich habe gerade einen neuen Artikel zur Nutzung der CSS Anchor API veröffentlicht, und nächste Woche soll sie in Chromium aufgenommen werden
      https://developer.chrome.com/blog/anchor-positioning-api
    • Den Stand der Browser-Unterstützung kann man hier sehen
      https://caniuse.com/css-anchor-positioning
    • Wenn es CSS Anchor Positioning in den letzten Jahren schon gegeben hätte, hätte mir das enorm viel Zeit gespart
    • Das ist das fehlende Kernstück
      Ich wollte letzte Woche etwas mit der neuen Popover API bauen und ausrollen, aber weil die Positionierungsunterstützung in allen Browsern unzureichend war, waren die Einsatzmöglichkeiten stark eingeschränkt
      Da nun offenbar auch Firefox als letzter Browser Anchor Positioning bereits in der Beta hat, dürfte es nicht mehr lange dauern
    • Erstaunlich, dass es im Jahr 2024 in HTML/CSS kein Tooltip-Attribut wie title gibt
  • Wenn man einen modalen Dialog braucht, gibt es auch das <dialog>-Element
    https://developer.mozilla.org/en-US/docs/Web/HTML/Element/di...

    • Wenn man aufklappbare/einklappbare Inhalte braucht oder mit etwas gutem Willen sogar ein „Dropdown“, kann man auch <details> verwenden
      Merkwürdigerweise scheint man bei <popover> im Gegensatz zu <dialog> oder <details> keinen deklarativen open-Status allein per Attribut setzen zu können
      Das wirkt wie eine fehlende Funktion, und ich hoffe, es gab gute Gründe für diese Entscheidung
      https://developer.mozilla.org/en-US/docs/Web/HTML/Element/de...
    • Ich möchte darauf hinweisen, dass es einiges an Arbeit braucht, um Animationen und allgemeines modales Verhalten auf das heute erwartete Niveau zu bringen
      Das ist durchaus machbar, aber keineswegs trivial
    • Wie bereits angemerkt sind Animationen schwieriger, aber es bringt Barrierefreiheit mit und unterstützt Schließen per Esc-Taste, eingebauten Backdrop und eingebautes Focus-Trapping
      Die Safari-Unterstützung hat gedauert, aber inzwischen kann man es überall verwenden
      Meiner Meinung nach ist das besser, als Tags selbst zusammenzubasteln
    • Das wird bereits in den ersten Absätzen des Artikels behandelt
  • Wenn das zusammen mit dem Fenstersystem des Host-Betriebssystems implementiert wäre, wäre diese Funktion definitiv nötig
    Im Moment müssen Popovers immer auf eine Weise nachgeahmt werden, die nicht immer gut funktioniert
    Zum Beispiel kann ein browsernatives <select> über die Grenzen des Browserfensters hinausragen, ohne dass man sich Sorgen machen muss, dass es abgeschnitten wird, aber schicke gefälschte Selects aus Toolkits wie Quasar können das nicht, wodurch die Platzierungsoptionen eingeschränkt sind
    Für eine saubere Umsetzung müsste unter win32 vermutlich jedes Popover ein eigenes natives HWND haben und unter Cocoa/macOS in einer eigenen NSView liegen
    Ich frage mich, ob Browser das tatsächlich so implementieren oder ob sie einfach nur innerhalb des Browserfensters darüberzeichnen

    • Diese Popovers sind einfach normale DOM-Knoten und werden mit normalem CSS gestaltet
      Wenn man Websites erlauben würde, außerhalb des vorgesehenen Viewports zu zeichnen, wäre es viel einfacher, Browser- oder Betriebssystemdialoge glaubwürdig nachzuahmen, abgesehen von extrem eingeschränkten Fällen wie alert(), confirm() und [title]
      Eine Seite könnte zum Beispiel das Entsperr-Widget einer Passwortmanager-Erweiterung imitieren
      Das ist ein großes Sicherheitsrisiko und meiner Meinung nach den begrenzten Nutzen nicht wert
      Das ist keine theoretische Sorge
      Betrüger bauen seit Jahren sehr überzeugende Fake-UIs, einschließlich gefälschter Popup-Fenster mit Browser-Chrome, die sich sogar ziehen ließen
      Dass sie nicht außerhalb der Viewport-Grenzen zeichnen können, war fast die einzige Einschränkung, die sie nicht umgehen konnten
    • Ich weiß nicht, wie nützlich so eine Funktion in der Praxis wäre
      Auf kleinen Geräten bedeckt der Webbrowser fast immer den ganzen Bildschirm, und selbst auf großen Monitoren berührt er normalerweise mindestens eine Ecke
    • Auch semantisch dürfte sich das leichter erkennen lassen
      Das gilt sowohl für Barrierefreiheit und Crawlbarkeit als auch für den Fall, dass jemand ein „Popups verbieten“-Plugin bauen möchte
    • Firefox unterstützt technisch die Möglichkeit, Teile von Seiteninhalt in ein separates Fenster auf Betriebssystemebene „herausplatzen“ zu lassen
      Diese Funktion wird über ein XUL-Element bereitgestellt, das nur in privilegiertem [X]HTML verfügbar ist, das im Hauptprozess des Browsers gerendert wird
      Wohl kaum ein Browser-Entwickler würde normalen Webseiten die Berechtigung geben wollen, randlose Betriebssystemfenster zu erzeugen
    • Es wirkt nicht so, als würden Web-Apps in absehbarer Zeit die vorgestellte native Integration ins Fenstersystem bekommen
      Dass einige Standard-Controls sich so verhalten, ist ein plattformspezifischer Nebeneffekt ihrer nativen Implementierung im Betriebssystem und nicht etwas, das zwingend so umgesetzt werden müsste
  • Der Browser hat einen eingebauten Popup-Blocker, daher wirkt es schon etwas komisch, dass man so eine API baut
    Ich weiß zwar, dass es einen Unterschied gibt, aber trotzdem
    Ich bin alt genug, um mich an die Popup-/Popunder-Kriege der späten 90er und frühen 2000er zu erinnern
    Diese Schlacht haben wir wohl gewonnen, aber der Krieg um unsere Aufmerksamkeit ist noch lange nicht vorbei

    • Das scheint mir ein Vergleich von zwei unterschiedlichen Dingen zu sein
      Ein Popover ist ein schwebendes Element, das bei Bedarf Kontextinformationen anzeigt
      Das Genannte ist etwas völlig anderes
    • Ich verstehe den Punkt, aber eigentlich sind das wohl keine vergleichbaren Dinge
      Popups werfen Müllfenster auf Betriebssystemebene aus und können im schlimmsten Fall sogar die Nutzung des Computers selbst behindern
      Ein Popover-Dialog ist erledigt, sobald man den Tab schließt
      Diese Art von Popover ist zum Anzeigen von Informationen ziemlich nützlich und wird schon seit langem verwendet
      Man kann sie nervig einsetzen, aber wie bei Modals gibt es auch viele echte Anwendungsfälle
    • Diese Reaktion sieht man oft, aber sie ergibt nicht ganz Sinn
      Schon jetzt kann man Popover mit vorhandenen div usw. umsetzen
      Beispiel: https://getbootstrap.com/docs/5.3/components/popovers/
      Der Unterschied ist, dass man Popover ohne magische Zusatzbibliothek umsetzen kann
      Selbst wenn man explizite „popover“-Elemente blockieren würde, würden die Leute weiter Custom-Libraries verwenden
    • Das ist kein Popup
      Menschen hassen Popups, weil sie aufdringlich sind und ein separates Fenster haben
      Diese API ersetzt div-Modals und spart Entwicklern Zeit und Code
    • Ursprünglich durchbrach die Implementierung von Popups die Grenze zwischen Anwendungsinhalt und Betriebssystem, und Popup-Blocker sollen genau das verhindern
      Diese API durchbricht diese Grenze nicht
      Wenn diese Grenze durchbrochen wird, leidet die Benutzbarkeit und Sicherheit des Systems, daher ist das keine gewünschte Richtung
  • Bei „Popover mit der Popover API sind immer nicht-modal. Wenn du ein modales Popover erstellen willst, ist das <dialog>-Element das Richtige“ frage ich mich, warum das so sein soll
    Das ist ein legitimer Anwendungsfall für Popover
    Besonders dann, wenn der Hintergrund beim Öffnen unscharf gemacht wird; und wenn man versehentliche Klicks auf unscharf dargestellte Buttons provozieren kann, frage ich mich, warum man diese Funktion überhaupt anbietet
    Wie ich sehe, kann man beide kombinieren
    So in der Art: „Wenn du Popover-Steuerung mit Dialog-Semantik kombinieren willst, kannst du ein <dialog>-Element zu einem Popover machen“
    Dann würde hier doch eher ein Attribut wie modal Sinn ergeben
    Man erkennt den Anwendungsfall ja offensichtlich an

    • Wahrscheinlich ist einer von mehreren Gründen, dass <dialog> schon viel früher existierte
  • Sehr gut
    Wenn ich es richtig verstanden habe, führt das weniger eine neue Funktion ein, sondern vereinfacht eher das, wofür man bisher ein modales div, ein Masken-div, ein Container-div und umständliches CSS zur Positionierung brauchte
    Dazu kommen Pseudoklassen, die das Styling erleichtern, gefällt mir

    • Damit wird auch grundlegende Funktionalität ohne JavaScript nutzbar
      Man muss keine versteckten Checkboxen mehr missbrauchen
      Ich weiß nicht, wie weit man bei Popovern mit Styling und Animationen ganz ohne JS kommt, aber Unterstützung ohne JS mit korrekter Fokusbehandlung ist gut
      Ich würde gern sagen, dass Unterstützung für Accessibility ebenfalls eingebaut ist, aber ich finde das in der aktuellen Spezifikation nicht
      Wenn damit auch die Benachrichtigung von Accessibility-Tools wie Screenreadern über Elemente abgedeckt wird, wäre das eine große Hilfe
      Denn wenn man es manuell macht, vergisst man so etwas ziemlich leicht
    • Diese API ermöglicht es, auch ohne JavaScript im DOM den Sichtbarkeitsstatus von Popover-Elementen zu steuern
      Das ist definitiv nützlich
  • Demo: https://mdn.github.io/dom-examples/popover-api

    • In der Demo mit verschachtelten Popovern kann man sich nicht diagonal von Pizza zu Ham bewegen
      Das liegt daran, dass offenbar niemand in Chrome oder Firefox eine Verzögerungszeit eingebaut hat, bevor das Untermenü verschwindet
      Jahrzehnte an UX-Forschung sind verloren gegangen, fast genau wie erwartet
      https://mdn.github.io/dom-examples/popover-api/nested-popove...
    • Laut Browser-Support-Tabelle sollte es funktionieren, aber in iOS Safari scheint es nicht zu gehen
  • Sieht cool aus, aber ich verstehe nicht, warum es auf dieser Seite kein einziges Bild gibt, das zeigt, was ein Popover ist

  • Hervorragend
    Hier ist eine Custom-Implementierung mit Stimulus unter Verwendung von Popper
    https://github.com/tramlinehq/tramline/blob/main/app/javascr...
    Und hier ist eine Implementierung für Dialoge
    https://github.com/tramlinehq/tramline/blob/main/app/javascr...