Infobox/Tooltips mit Popover

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Popovers sind überall im Web zu finden. Man sieht sie in Menüs, Tooltipps und Dialogen, die sich als Kontoeinstellungen, Offenlegungs-Widgets und Warenkorbvorschauen manifestieren können.

Obwohl diese Komponenten weit verbreitet sind, war ihre Erstellung in Browsern bisher überraschend kompliziert. Du musstest neben der Kernfunktionalität deines Popovers Skripte hinzufügen, um Fokus sowie Öffnungs- und Schließzustand mit Maus, Tastatur und Touchgeräten zu verwalten. Die open-ui.org hat es sich zur Aufgabe gemacht, für solche UI-Elemente optimierte Modelle zu entwerfen und diese zur Standardisierung einzureichen.[1]

Dieses Tutorial zeigt, wie du mit der neuen Popover API[2][3] schnell und einfach Tooltipps und Popups erstellst, die diese Funktionalitäten bereits browserseitig mitbringen. Es ist kein kompliziertes CSS oder gar JavaScript nötig!

Beachte: Die Popover API funktioniert (Stand April 2024) in allen Browsern! Der Firefox unterstützt die Popover API seit Version 125. Für ältere Browser-Versionen sind die Beispiele vorerst weiterhin mit einem Polyfill ausgestattet[4]:
<script
  src="https://cdn.jsdelivr.net/npm/@oddbird/popover-polyfill@latest"
  crossorigin="anonymous"
  defer
></script>

popover und popovertarget

Im ersten Beispiel zeigen wir, wie wenig HTML nötig ist, um ein Popover auf- und zuklappen zu können:

Popover nur mit HTML! ansehen …
<button popovertarget="additional-info"> → mehr Infos </button>
<div id="additional-info" popover>
	<h4>Zusatz-Info</h4>
	<p>In einem HTML-Element mit popover-Attribut 
       können weitere Informationen präsentiert werden.<p>
</div>

Die wohl jedem bekannten button- und div-Elemente erhalten zwei neue Attribute:

  1. popovertarget verbindet den button mit der id des aufzuklappenden Elements
  2. popover liefert die Funktionalität. Es ist ein Universalattribut, d. h.

du kannst auch andere Elemente wie aside, form, etc auf- und zuklappen.

Das popover-Attribut[5] kümmert sich mit seinem Standardverhalten um …

  • Beförderung auf den Top-Layer (oberste Ebene). Popovers werden auf einer separaten Ebene über dem Rest der Seite angezeigt, ohne dass du einem z-index setzen musst.
  • Standardmäßige Fokusverwaltung. Wenn man das Popover öffnet, wird der nächste tabindex innerhalb des Popovers angesteuert.
  • leichtes Verlassen (light-dismiss)-Funktionalität. Wenn man außerhalb des Popover-Bereichs klickt oder ESC drückt, wird das Popover geschlossen und der Fokus zurückgegeben.
  • Zugängliche Komponentenbindungen. Semantische Verknüpfung eines Popover-Elements mit einem Popover-Auslöser.

explizites Beenden

Im Gegensatz zum light dismiss, muss man einen modalen Dialog explizit beenden, z. B. über eine Schaltfläche zum Schließen und die Escape-Taste (im Zweifelsfall am besten beides hinzufügen).

Etwas Ähnliches kannst du mit dem popovertargetaction-Attribut erreichen.

Popover mit explizitem Beenden ansehen …
<button popovertarget="additional-info"> → mehr Infos </button>

<div id="additional-info" popover>
  <h4></h4>
  <p><p>
  <button popovertarget="additional-info" popovertargetaction="hide" class="close-btn">
    <span aria-hidden="true">X</span>
    <span class="sr-only">Schließen</span>
</button>
</div>

Das Beispiel erhält nun einen zweiten Button, der ebenfalls über das popovertarget mit dem popover-div verbunden ist. Das Popover kann nun aufgrund von popovertargetaction="hide" mit einem Klick auf diesen Button - aber auch mit einem light dismiss - geschlossen werden.

mehrere Popover anzeigen

Das oben erwähnte popover-Attribut hat als Defaultwert auto - Ein Öffnen eines Popovers schließt automatisch andere geöffnete Popups.

Mit dem Wert popover=manual kannst du mehrere Popovers gleichzeitig offen halten:

mehrere Popover anzeigen ansehen …
<button popovertarget="additional-info1"> → mehr Infos </button>

<div id="additional-info1" popover=manual>
  <h4>Zusatz-Info 1</h4>
  <p><p>
  <button popovertarget="additional-info1" popovertargetaction="hide" class="close-btn"></button>
</div>

<button popovertarget="additional-info2"> → Popover 2</button>

<div id="additional-info2" popover=manual>
  <h4>Zusatz-Info 2</h4>
  <p><p>
  <button popovertarget="additional-info2" popovertargetaction="hide" class="close-btn"></button>
</div>

Damit die Popovers nicht übereinander liegen, wurden Aussehen und Positionierung getrennt:

[popover] {
  background: #fffbf0;
  border: thin solid #e7c157;
  max-width: 20em;
  position: absolute;
  padding: 1rem;
}

#additional-info1 {
  margin: 2rem auto;
}

#additional-info2 {
  margin: 14rem auto;
}

Alle Elemente, die ein popover-Attribut enthalten, werden mit dem Attributsselektor ausgewählt und erhalten entsprechende Formatierungen.

Über die Id werden die Popovers jeweils passend positioniert.

Gestaltung mit CSS

Inline-Tooltips

In diesem Beispiel erhält ein Text zu mehreren Fachbegriffen Zusatzinformationen:

Inline-Tooltips mit Popover ansehen …
<p>
  <button popovertarget="t1">Tooltipps</button>
  <span id="t1" popover>Infobox, die zusätzliche Informationen enthält.</span></p>
<p>
  <button popovertarget="t2">Popovers</button>
  <span id="t2" popover>Element, das in der obersten Ebene aufplobbt.</span><button popovertarget="t3">open-ui.org</button>
  <span id="t3" popover>W3C Community Group, die sich die Verbesserung des Web auf die Fahnen geschrieben hat.</span>
</p>

Die Fachbegriffe werden als buttons innerhalb des Fließtexts notiert - direkt dahinter als span-Element der Informationstext. Wie in den oberen Beispielen sind die buttons über das popovertarget-Attribut mit der id des Popovers verbunden.

Du kannst den Tooltip als Sprechblase gestalten, wenn du ein weiteres Pseudoelement verwendest[6]:

Sprechblase mit Pseudoelement
[popover] {
  background: #fffbf0;
  border: medium solid var(--accentColor);
  max-width: 20em;
  padding: 1rem;
  overflow: unset;
}

/* erzeugt ein Dreieck */
[popover]::before {
	content:"";
	--triangle-width: 2em;
	display: block;
	position:absolute;
	left: var(--triangle-width);
	bottom: calc(-1 * var(--triangle-width)); 
  border-width: var(--triangle-width) calc(0.5 * var(--triangle-width)) 0;
	border-style: solid;
  border-color: var(--accentColor) transparent;
	transition: all 0.5s;		
}

body {
	  --accentColor: #dfac20;
}

Das durch ::before erzeugte Pseudoelement hat keinen Inhalt und keine festgelegte Größe, aber einen 2em breiten Rahmen, der aber nur oben rot und sonst transparent ist. So wird ein gelbes Dreieck erzeugt, das den Eindruck einer Sprechblase erweckt.

Leider sind die Tooltips mittig zentriert. Ideal wäre, sie direkt über dem button zu positionieren. Dies wurde früher mit einer absoluten Positionierung - ausgehend von dem letzten relativ positionierten Elternelement - erreicht. Allerdings konnte sein, dass Tooltipps am Rand des Viewport über diesen herausragten und so nicht sichtbar waren.

Anchor Positioning

Nach heutigem Stand kann man nur mit HTML und CSS nicht steuern, ob ein Tooltip außerhalb des Viewports - und damit nicht sichtbar - dargestellt wird. Mit JavaScript und der Intersection Observer API könnte man berechnen, ob sich ein Element im sichtbaren Bereich befindet.

Das W3C entwickelt für eine reine CSS-Lösung derzeit das CSS Anchor Positioning Module, mit dem für diesen Fall alternative Formatierungen angegeben werden können.

Beachte: Anchor Positioning funktioniert (Stand Oktober 2023) nur in Chrome Canary hinter einem flag, deshalb sind die Beispiele vorerst mit einem Polyfill ausgestattet[7]:
<script type="module">
  if (!("anchorName" in document.documentElement.style)) {
    const { default: polyfill } = await import("https://unpkg.com/@oddbird/css-anchor-positioning/dist/css-anchor-positioning-fn.js");

    polyfill(true);
  }
</script>

ToDo (weitere ToDos)

Beispiel entwickeln, wenn Browserunterstützung besser ist.

--Matthias Scharwies (Diskussion) 06:22, 22. Okt. 2023 (CEST)

Fazit

Die neue Popover API ist überraschend unkompliziert und einfach zu implementieren. Für „normale“ Popover ist sie dem dialog-Element vorzuziehen, das seine Stärken eher bei modalen Dialogen hat.[8]

  • modale Dialogfenster
    • dialog-Element
    • modal vs nichtmodal
    •  :backdrop

    Das UI-Element für Web-Apps

  • Bilder präsentieren -
    Lightbox mit Popover
    Landscape.svg
  • Akkordeon mit <details>
    • details und summary
    • Akkordeon
    • Registerkarten (Tab Panels)

    Besonders interessant für FAQs, um Inhalte übersichtlich zu präsentieren.


Weblinks

  1. open-ui.org: Popover API (Explainer)
  2. WHATWG: 6.12 The popover attribute
  3. MDN: Popover API
  4. Popover Attribute Polyfill (github.com)
  5. developer.chrome.com: Introducing the popover API von Una Kravets, May 23, 2023
  6. Sprechblasen mit CSS:
  7. Anchor Positioning Polyfill (github.com)
  8. hidde.blog: Dialogs and popovers seem similar. How are they different?