Wer kennt es nicht? Es wird wieder Zeit für ein Tooltip auf der Webseite, um eine neue Werbung noch präsenter darzustellen und den Nutzer richtig schön nerven zu können? Welche JavaScript Libraries kann ich jetzt verwenden, um so viele Datenvolumen wie möglich meines Nutzers zu verbrauchen? Wie wär es mit React oder Vue oder einem extra Plugin für jQuery, das sich darum kümmert? Gute Idee!
Natürlich beabsichtigst du, einen bedeutungsvollen Hinweis darzustellen und so wenig Datenvolumen des Nutzers dafür zu verbrauchen wie möglich. Dafür gibt es inzwischen eine neue Möglichkeit über die Popover API. Diese stellt neue Möglichkeiten bereit, das Ganze zu realisieren. Das Besondere ist, du benötigst nicht unbedingt JavaScript dafür. Denn die Popover API stellt unter anderem zwei neue Attribute bereit: popover
und popovertarget
damit lassen sich bereits einfache Popovers ohne JavaScript definieren und via CSS kannst du noch ein individuelles Styling einrichten. Natürlich gibt es auch für die Interaktion mit der Popover API neue JavaScript-Methoden, die du bei Bedarf verwenden kannst.
Wichtig neben dem popover
Attribute und den entsprechenden Schnittstellen für JavaScript, um darauf zuzugreifen, gibt es auch noch das Dialog-Element, diese ist für größere Modale mit Informationen und Interaktionen besser geeignet, da unter anderem die Barrierefreiheit noch etwas besser ist um zum Beispiel keine anderen Elemente zu fokussieren außerhalb des Modals. Das popover
Attribute macht dort weniger Vorgaben und ist spannender, um Elemente explizit in den Top-Layer zu verschieben und dort offen zu haben. Für diesen Artikel habe ich einige Beispiele in einem Repository gesammelt, andere findest du als Live Beispiel im Folgenden.
Die neue Popover API stellt eine einfache Möglichkeit dar, über Attribute ein Popover zu erzeugen, das im Top-Layer vom document
dargestellt wird. Zu beachten ist, dass der Top-Layer immer über allen Elementen liegt. Es lässt sich nicht durch den z-index
der Seite beeinflussen. Dadurch können kurze Informationen und Hinweise immer über der Webseite angezeigt werden. Das Popover Attribut können zum Beispiel für kleine Hinweise oder Toast-Messages verwendet werden.
Eine einfache Umsetzung benötigt nur einen Button mit einem Attribute popovertarget
in diesem wird die ID des Elementes definiert, das bei dem Drücken des Buttons ausgelöst wird und sich als Popover öffnen soll. Das Element, das sich als Popover öffnen können soll, benötigt das Attribute popover
ohne einen Wert und eine ID, um es dann ansteuern zu können.
<button popovertarget="popover-element">Anzeigen/Schließen</button>
<div id="popover-element" popover>
<h1>Hallo Welt!</h1>
<p>...</p>
</div>
Es gibt noch zusätzliche Optionen, die wir auf dem Button definieren können. Zum Beispiel ist standardmäßig der Button ein Toggle zwischen Anzeigen und Schließen. Über eine popovertargetaction
können wir die Werte hide
, show
oder toggle
setzen, wobei toggle
der Standardwert ist, falls das Attribut nicht vorhanden ist. So lässt sich etwa ein dedizierter Schließen-Button innerhalb des Popovers definieren.
<button popovertarget="popover-element" popovertargetaction="show">Anzeigen</button>
<div id="popover-element" popover>
<h1>Popover mit Schließen Button</h1>
<button popovertarget="popover-element" popovertargetaction="hide">Schließen</button>
</div>
Zu beachten ist, dass ein Popover sich auch immer über die ESC-Taste schließen lässt, um sich auch schnell via Tastatur schließen zu lassen. Zusätzlich kann auch immer außerhalb des Popovers geklickt werden, um dieses automatisch zu schließen. Alternative, wenn man den Nutzer zu einer bewussten Interaktion zwingen möchte, kann man Alternative zu dem auto
genannten Modus auch mit dem manual
Modus arbeiten, diese verändert das Verhalten des Popovers. Dabei wird dann das popover
Attribute auf manual
gesetzt, dadurch muss explizit ein Button oder eine eigene JavaScript-Aktion zum Schließen verwendet werden und eine Steuerung durch Drücken außerhalb des Popovers oder Verwendung der ESC-Taste ist nicht mehr möglich.
Neben der Verwendung der Popovers ausschließlich via HTML kann man die Popovers auch via JavaScript ansteuern, um zu interagieren. Das könnte zum Beispiel dafür verwendet werden, Popovers dynamisch nach einer Zeit von 10 Sekunden zu schließen.
Es gibt drei Methoden auf dem Element, das das popover
Attribute hat, die eigentlich recht selbsterklärend sind:
hidePopover()
entfernt, das Popover aus dem TopLayer und die Browser Styles setzen es dann auf display: none
.showPopover()
fügt das Element zum TopLayer hinzu.togglePopover()
wechselt zwischen den beiden States also entweder show
oder hide
.Zusätzlich haben wir noch zwei Events zur Verfügung. Das beforetoggle
Event wird ausgelöst, bevor ein State wechsel erfolgt. Das toggle
Event, nachdem der State wechsel erfolgt ist, darüber könnten dann etwa weitere Veränderungen an der Seite stattfinden. Ein einfacher Beispielcode, der eine kurze Übersicht über die Methoden und Möglichkeiten gibt.
const popoverElement = document.getElementById('popover-element');
popoverElement.addEventListener('beforetoggle', (event) => {
console.log('beforetoggle', event);
});
popoverElement.addEventListener('toggle', (event) => {
console.log('toggle', event);
});
popoverElement.togglePopover();
popoverElement.hidePopover();
popoverElement.showPopover();
Es gibt unterschiedliche Möglichkeiten, auf das Styling der Popovers einzugreifen. Wichtig zu wissen ist, dass regulär das Popover vom Browser eine display: none
erhält, über den Selektor [popover]:not(:popover-open):not(dialog[open])
diese sollten wir unter keinen Umständen überschreiben, denn darüber passiert letztlich das Ausblenden mit display: none
. Über die :popover-open
Pseudo Klasse können wir das Styling anpassen, wenn das Popover geöffnet ist. Ich empfehle dir, alle individuellen Anpassungen immer in Kombination mit diesem Selektor zu machen, um nicht aus Versehen Anpassungen auf das geschlossene Popover anzuwenden.
Zusätzlich haben wir eine neues Pseudo Element, das wir verwenden können ::backdrop
darüber können wir den Hintergrund hinter dem geöffneten Popover Stylen zum Beispiel können wir einen backdrop-filter
definieren, um eine Unschärfe zu erzeugen oder mit einem leicht Transparenten Hintergrund verwenden, um alles andere abzudunkeln. Folgendes Beispiel zeigt dir einmal, was möglich ist mit der Verwendung von ::backdrop
und :popover-open
.
#popover-element:popover-open {
font-family: sans-serif;
border: none;
border-radius: 8px;
padding: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
#popover-element::backdrop {
background-color: rgba(0, 10, 10, 0.5);
backdrop-filter: blur(5px);
}
<button popovertarget="popover-element">Anzeigen</button>
<div id="popover-element" popover>
<p>Ein kleiner Hinweis für dich!</p>
</div>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, <a href="">sed</a> diam nonumy eirmod tempor invidunt ut labore et dolore magna
aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd
gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
Einen kleinen Schmankerl habe ich noch für euch, der die Popover API erst so richtig interessant macht, und zwar das neue Anchore Positioning. Darüber können Elemente relativ zu anderen Elementen positioniert werden, ohne dass sie in einem gemeinsamen Element sitzen müssen. Dadurch können wir den Tooltip relativ zum Button immer anzeigen aufgrund einer dynamischen Berechnung. Achtung, der Browser Support ist leider bis jetzt (stand: Sep. 2024) nicht so hervorragend und es ist noch etwas Zukunftsmusik damit zu arbeiten. Im Firefox und Safari-Browser wird dieses Beispiel nicht korrekt funktionieren.
button[popovertarget="popover-element"] {
anchor-name: --popover-anchor;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
padding: 8px 16px;
cursor: pointer;
margin-left: 16px;
}
#popover-element:popover-open {
position: absolute;
position-anchor: --popover-anchor;
top: calc(anchor(bottom) + 16px);
left: anchor(left);
margin: 0;
padding: 16px;
line-height: 1;
font-family: sans-serif;
border: none;
border-radius: 8px;
box-shadow: 0 2px 4px 2px rgb(0 0 0 / 30%);
}
#popover-element:popover-open p {
position: relative;
margin: 0;
}
<h1>
Die Popover API ein Tooltip Beispiel
<button popovertarget="popover-element">Info</button>
</h1>
<div id="popover-element" popover>
<p>Ein kleiner Tooltip</p>
</div>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, <a href="">sed</a> diam nonumy eirmod tempor invidunt ut labore et dolore magna
aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd
gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
Über das neue anchor-name
CSS Property können wir ein Element definieren, das einen Anchor ist und über position-anchor
können wir dieses Element für die Positionierung heranziehen. Über anchor(left), anchor(bottom), ...
können wir auf den jeweiligen Wert zugreifen und unsere Elemente entsprechend positionieren; mit der calc
Methode können wir dann zum Beispiel auch noch zusätzliche Abstände ergänzen.
Die Browser-Kompatibilität von Popover ist inzwischen sehr hoch, auch im neuen Baseline-Programm ist die Funktion seit dem 16. April 2024 als komplett verfügbar aufgeführt. Weitere Informationen dazu findest du auch hier: https://webstatus.dev/features/popover
Falls du noch mehr zum Baseline-Status wissen willst, kann ich dir das Dokument empfehlen.
Die Popover API bietet eine vielversprechende Möglichkeit, auch eigene individuelle Elemente im Top-Layer anzuordnen und zu verwenden. Es ist schön zu sehen, dass kein Dialogelement mehr dafür missbraucht werden muss, wenn der semantische Zweck nicht erfüllt wird. Ich freue mich perspektivisch darauf, dass man immer weniger auf extrem hohe z-index Werte angewiesen ist, um sicherzustellen, dass ein Element wirklich auf höchster Ebene angezeigt wird.
Hinterlasse mir gerne einen Kommentar zum Artikel und wie er dir weitergeholfen hat beziehungsweise, was dir helfen würde das Thema besser zu verstehen. Oder hast du einen Fehler entdeckt, den ich korrigieren sollte? Schreibe mir auch dazu gerne ein Feedback!
Es sind noch keine Kommentare vorhanden? Sei der/die Erste und verfasse einen Kommentar zum Artikel "Popover API: Smarte Popovers für bessere Nutzererfahrung"!