Tooltips und Overlays ohne JavaScript
Tooltips, Dropdowns und kontextbezogene Overlays wurden jahrelang entweder mit JavaScript oder mit fragilen CSS-Hacks gelöst. CSS Anchor Positioning ändert das grundlegend: anchor(), position-anchor und @position-try ermöglichen präzise, kontextbewusste Positionierung direkt im Stylesheet — ohne eine einzige Zeile JavaScript.
Inhaltsverzeichnis
- 1. Das Problem mit Tooltip-Positionierung vor Anchor Positioning
- 2. Grundlagen: anchor-name und position-anchor
- 3. Die anchor()-Funktion: präzise Kantenbezüge
- 4. @position-try: automatisches Fallback-Positioning
- 5. inset-area: Rasterbasiertes Positionieren
- 6. Praxisbeispiel: Tooltip-Komponente vollständig in CSS
- 7. Dropdown-Menü mit CSS Anchor Positioning
- 8. Browser-Support und Progressive Enhancement
- 9. Anchor Positioning im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Das Problem mit Tooltip-Positionierung vor Anchor Positioning
Die Positionierung von Tooltips, Dropdowns und kontextbezogenen Overlays war jahrelang eine der unbefriedigendsten Aufgaben in der Frontend-Entwicklung. Das Grundproblem: Ein Overlay muss relativ zu seinem Auslöser positioniert werden — also zu einem Element, das irgendwo im DOM steht — während das Overlay selbst oft an einem anderen Ort im Dokumentbaum lebt, etwa direkt vor dem schließenden <body>-Tag, um Stacking-Context-Probleme zu vermeiden. CSS Anchor Positioning adressiert genau diesen Konflikt zwischen DOM-Position und visueller Positionierung.
Frühere Lösungen setzten entweder auf JavaScript-Bibliotheken wie Popper.js oder Floating UI, die das Overlay per getBoundingClientRect() dynamisch positionieren, oder auf CSS-Hacks mit position: relative auf dem Elternelement, was das Overlay im DOM an den Auslöser bindet und Stack-Probleme erzeugt. Beide Ansätze haben Nachteile: JavaScript-Lösungen laden zusätzliche Bytes und reagieren nicht immer synchron auf Layout-Änderungen. CSS-Hacks brechen bei komplexen Layouts mit verschachtelten Stacking Contexts. CSS Anchor Positioning löst beides nativ im Browser.
2. Grundlagen: anchor-name und position-anchor
Das Herzstück von CSS Anchor Positioning sind zwei neue CSS-Properties. Die Property anchor-name markiert ein beliebiges Element als Anker und weist ihm einen CSS-Custom-Property-ähnlichen Bezeichner zu — zum Beispiel anchor-name: --my-button. Das Overlay, das sich an diesem Anker ausrichten soll, referenziert diesen Namen über position-anchor: --my-button. Damit sind die beiden Elemente logisch verknüpft, egal wo sie im DOM-Baum stehen. Die Verbindung existiert ausschließlich im CSS — kein JavaScript, keine DOM-Mutation.
Das Overlay muss position: absolute oder position: fixed gesetzt haben, damit CSS Anchor Positioning greift. Mit position: fixed bleibt das Overlay beim Scrollen an der richtigen Position relativ zum Anker, weil der Browser den Offset automatisch aktualisiert. Das ist ein erheblicher Vorteil gegenüber JavaScript-Lösungen, die auf Scroll-Events lauschen müssen. Das Anchor-Positioning-System arbeitet im selben Layout-Pass wie alle anderen CSS-Eigenschaften — keine asynchrone Repositionierung, kein Layout-Thrashing.
/* Step 1: Mark the trigger element as an anchor */
.tooltip-trigger {
anchor-name: --tooltip-anchor;
/* Works on any element: button, span, div, img */
}
/* Step 2: Link the overlay to the anchor */
.tooltip {
position: fixed; /* or absolute — fixed survives scrolling */
position-anchor: --tooltip-anchor;
/* Step 3: Position relative to anchor edges */
bottom: anchor(top); /* overlay bottom = anchor top */
left: anchor(center); /* overlay left = anchor horizontal center */
translate: -50% -0.5rem; /* center and add gap */
/* Visibility: linked to :popover-open or :hover chain */
opacity: 0;
pointer-events: none;
transition: opacity 0.15s ease;
}
.tooltip-trigger:hover .tooltip,
.tooltip-trigger:focus .tooltip {
opacity: 1;
pointer-events: auto;
}
3. Die anchor()-Funktion: präzise Kantenbezüge
Die anchor()-Funktion ist das Werkzeug, mit dem man konkrete Koordinaten aus dem Anker-Element ausliest. Sie kann in den Inset-Properties des Overlays verwendet werden: top, right, bottom, left, inset-block-start, inset-inline-end und ähnliche. Als Argument nimmt anchor() eine Kantenbeschreibung: top, bottom, left, right, center, start, end oder einen Prozentwert. Ein optionales zweites Argument ist ein Fallback-Wert, falls der Anker nicht existiert oder nicht berechnet werden kann.
Die Grammatik ist bewusst logisch: bottom: anchor(top) bedeutet, dass die untere Kante des Overlays mit der oberen Kante des Ankers fluchtet. left: anchor(right) setzt das Overlay rechts neben den Anker. Kombiniert man das mit margin oder translate, lassen sich feine Abstände realisieren. Besonders elegant ist anchor(center), das die Mittellinie des Ankers — horizontal oder vertikal, je nach Kontext — zurückgibt. CSS Anchor Positioning kennt auch die Funktion anchor-size(), die die Breite oder Höhe des Ankers zurückgibt und es erlaubt, das Overlay auf genau dieselbe Breite zu setzen wie seinen Auslöser.
4. @position-try: automatisches Fallback-Positioning
Eines der mächtigsten Features von CSS Anchor Positioning ist die At-Rule @position-try. Sie löst das klassische Viewport-Overflow-Problem: Wenn ein Tooltip oben nicht genug Platz hat, soll er stattdessen unten erscheinen. Wenn ein Dropdown rechts über den Viewport hinausragt, soll es sich nach links ausrichten. Bisher erforderte diese Logik JavaScript, das die Viewport-Grenzen prüft und CSS-Klassen wechselt.
Mit @position-try --fallback-name { … } definiert man alternative Positioning-Regeln. Die Property position-try-fallbacks am Overlay nimmt eine geordnete Liste dieser Fallbacks entgegen. Der Browser probiert die Optionen der Reihe nach durch und wählt die erste, bei der das Overlay vollständig im Viewport liegt — automatisch, ohne JavaScript, bei jedem Layout-Reflow. CSS Anchor Positioning kombiniert das mit der Property position-try-order, die steuert, ob der Browser die Variante mit dem meisten verfügbaren Platz bevorzugt, anstatt stur die Reihenfolge abzuarbeiten.
/* Define fallback positioning strategies */
@position-try --above {
bottom: anchor(top);
left: anchor(center);
translate: -50% -0.5rem;
}
@position-try --below {
top: anchor(bottom);
left: anchor(center);
translate: -50% 0.5rem;
}
@position-try --right {
top: anchor(center);
left: anchor(right);
translate: 0.5rem -50%;
}
@position-try --left {
top: anchor(center);
right: anchor(left);
translate: -0.5rem -50%;
}
/* Apply: browser picks first fitting option */
.tooltip {
position: fixed;
position-anchor: --tooltip-anchor;
/* Primary position */
bottom: anchor(top);
left: anchor(center);
translate: -50% -0.5rem;
/* Automatic overflow handling */
position-try-fallbacks: --above, --below, --right, --left;
position-try-order: most-space; /* prefer option with most available space */
}
5. inset-area: Rasterbasiertes Positionieren
Neben der anchor()-Funktion gibt es mit inset-area eine zweite, konzeptuell andere Möglichkeit zur Positionierung in CSS Anchor Positioning. Das Property denkt in einem gedachten 3×3-Raster rund um das Ankerelement: oben links, oben mitte, oben rechts, links mitte, mitte, rechts mitte, unten links, unten mitte, unten rechts. Man spricht von Regionen. Mit inset-area: top wird das Overlay in die obere Mitte platziert, mit inset-area: end start in die logische untere linke Ecke.
Der Vorteil von inset-area gegenüber der anchor()-Funktion liegt in der Lesbarkeit: Man beschreibt die gewünschte Region, nicht konkrete Kantenwerte. Das Overlay passt sich automatisch an die Ankergröße an. CSS Anchor Positioning erlaubt auch zweiwertige inset-area-Angaben wie inset-area: bottom span-right, das die gesamte untere Reihe vom Ankermittelpunkt nach rechts abdeckt — ideal für kontextmenüartige Overlays. Die Kombination von inset-area mit position-try-fallbacks macht es trivial, Overlays zu schreiben, die sich automatisch an den verfügbaren Viewport-Platz anpassen.
6. Praxisbeispiel: Tooltip-Komponente vollständig in CSS
Eine vollständige Tooltip-Komponente mit CSS Anchor Positioning kommt ohne eine einzige Zeile JavaScript aus. Das Popover-API des Browsers übernimmt die Sichtbarkeitssteuerung: Das Tooltip-Element erhält popover als Attribut, der Auslöser-Button erhält popovertarget. Der Browser verbindet beides automatisch und kümmert sich um Accessibility-Attribute wie aria-expanded und Fokusverwaltung. Das CSS übernimmt ausschließlich die Positionierung und Animation.
Das Zusammenspiel von Popover-API und CSS Anchor Positioning ist besonders stark: Da das Popover-Element im Top-Layer des Browsers gerendert wird — also oberhalb aller normalen Stacking Contexts — entfallen die klassischen Z-Index-Probleme vollständig. Gleichzeitig erlaubt CSS Anchor Positioning, das Overlay trotzdem präzise relativ zum Auslöser zu platzieren, auch wenn der Auslöser tief in einem verschachtelten Stacking Context liegt. Die Kombination beider APIs ist der eigentliche Durchbruch für JavaScript-freie Overlays.
/* Complete CSS-only tooltip using Popover API + Anchor Positioning */
/* Anchor: the trigger button */
[popovertarget="my-tooltip"] {
anchor-name: --tooltip-btn;
}
/* The tooltip popover */
#my-tooltip {
/* Popover resets to display:none by default */
position: fixed;
position-anchor: --tooltip-btn;
inset: auto; /* reset default popover insets */
/* Position above the anchor */
bottom: calc(anchor(top) + 0.5rem);
left: anchor(center);
translate: -50% 0;
/* Size and style */
max-width: 20rem;
padding: 0.5rem 0.75rem;
border-radius: 0.5rem;
background: #1e1b4b;
color: #ede9fe;
font-size: 0.875rem;
border: none;
box-shadow: 0 4px 24px rgba(74,29,150,0.35);
/* Automatic flip if not enough space above */
position-try-fallbacks: flip-block;
/* Smooth entry animation (uses @starting-style) */
transition: opacity 0.15s ease, scale 0.15s ease, display 0.15s ease allow-discrete;
opacity: 1;
scale: 1;
}
/* Before opening (entry animation start state) */
@starting-style {
#my-tooltip:popover-open {
opacity: 0;
scale: 0.95;
}
}
/* Hidden state */
#my-tooltip:not(:popover-open) {
opacity: 0;
scale: 0.95;
}
7. Dropdown-Menü mit CSS Anchor Positioning
Dropdown-Menüs sind ein weiterer zentraler Anwendungsfall für CSS Anchor Positioning. Das klassische Problem: Ein Navigations-Dropdown muss unterhalb seines Auslösers beginnen und mit seiner linken Kante fluchten — egal wie breit das Menü ist. Mit CSS Anchor Positioning schreibt man top: anchor(bottom) und left: anchor(left). Wenn das Menü den rechten Viewport-Rand überschreiten würde, greift automatisch ein @position-try-Fallback, der die rechte Kante des Menüs an der rechten Kante des Auslösers ausrichtet.
Ein häufiges Muster bei Dropdown-Menüs ist die Breitenanpassung: Das Dropdown soll mindestens so breit sein wie sein Auslöser. Mit min-width: anchor-size(width) ist das in einer Zeile CSS erledigt. CSS Anchor Positioning kennt neben anchor-size(width) auch anchor-size(height), anchor-size(inline) und anchor-size(block) für schreibrichtungsunabhängiges Sizing. Das ersetzt komplette JavaScript-Funktionen, die bisher per getBoundingClientRect() die Auslöserbreite auslasen und per style.minWidth auf das Dropdown übertrugen.
8. Browser-Support und Progressive Enhancement
Der Browser-Support für CSS Anchor Positioning ist seit 2025 erfreulich breit, aber noch nicht universell. Chrome und Edge unterstützen die vollständige Spezifikation ab Version 125. Firefox hat Support ab Version 131 geliefert. Safari hat die Grundfunktionen ab Version 18 implementiert, wobei einige fortgeschrittene Features wie position-try-order: most-space noch fehlen. Für Produktions-Deployments empfiehlt sich eine Feature-Detection mit @supports (anchor-name: --x).
Progressive Enhancement ist bei CSS Anchor Positioning gut umsetzbar: Der Fallback für nicht unterstützende Browser ist eine klassische Positionierung mit position: absolute relativ zum Elternelement. Das Overlay funktioniert dann möglicherweise nicht perfekt bei allen Viewport-Größen, aber es ist sichtbar und nutzbar. In einem @supports-Block ergänzt man dann die Anchor-Positioning-Regeln. So profitieren moderne Browser von der präzisen Positionierung, während ältere Browser ein funktionales Fallback bekommen — ohne JavaScript in beiden Fällen.
9. Anchor Positioning im direkten Vergleich
Der Vergleich zwischen klassischen Tooltip-Techniken und CSS Anchor Positioning zeigt die Vorteile in mehreren Dimensionen: Bundle-Größe, Accessibility, Wartbarkeit und Korrektheit bei komplexen Layouts.
| Kriterium | Popper.js / Floating UI | CSS Anchor Positioning | Vorteil |
|---|---|---|---|
| Bundle-Größe | ~12 KB (Floating UI core) | 0 KB (Browser-nativ) | Kein Drittanbieter-Paket |
| Viewport-Flip | JS-Logik, Scroll-Events | @position-try, automatisch | Kein Event-Listener |
| Stacking Context | Z-Index-Management nötig | Top-Layer via Popover-API | Keine Z-Index-Konflikte |
| Accessibility | Manuelle ARIA-Pflege | Popover-API, Browser verwaltet | aria-expanded, Fokus automatisch |
| Breite des Overlays | getBoundingClientRect() + JS | anchor-size(width) | Eine CSS-Zeile |
Die Tabelle zeigt: CSS Anchor Positioning ist nicht nur eine technische Spielerei, sondern ein ernsthafter Ersatz für JavaScript-basierte Positioning-Libraries in modernen Projekten. Der einzige echte Nachteil bleibt der noch nicht vollständige Browser-Support, der Progressive Enhancement erfordert. Sobald alle relevanten Browser die Spezifikation vollständig implementiert haben, entfällt der Rechtfertigungsbedarf für Popper.js in neuen Projekten vollständig.
Mironsoft
Modernes CSS, Frontend-Architektur und Performance-Optimierung
JavaScript-freie UI-Komponenten für Ihr Projekt?
Wir setzen moderne CSS-APIs wie Anchor Positioning, Popover-API und View Transitions in Ihrer Codebasis ein — für schlankere Bundles, bessere Accessibility und weniger JavaScript-Abhängigkeiten.
CSS-Audit
Bestehende Tooltip- und Overlay-Implementierungen analysieren und modernisieren
Komponenten-Entwicklung
Tooltips, Dropdowns und Popovers als progressive-enhanced CSS-Komponenten
Bundle-Optimierung
Popper.js und ähnliche Libraries durch native CSS-Lösungen ersetzen
10. Zusammenfassung
CSS Anchor Positioning löst ein fundamentales Problem der Webentwicklung: die Positionierung von Overlays relativ zu beliebigen Elementen im DOM, unabhängig von deren Position im Dokumentbaum. Die drei Kernkonzepte — anchor-name und position-anchor für die Verknüpfung, die anchor()-Funktion für präzise Kantenbezüge und @position-try für automatisches Overflow-Handling — ersetzen JavaScript-Bibliotheken wie Popper.js für die meisten Anwendungsfälle vollständig. In Kombination mit dem Popover-API des Browsers entfallen auch Z-Index-Probleme und manuelle Accessibility-Implementierungen.
Der Browser-Support hat 2025 einen Reifegrad erreicht, der CSS Anchor Positioning in neuen Projekten mit Progressive Enhancement rechtfertigt. Für Projekte, die noch ältere Browser unterstützen müssen, ist der Einsatz in einem @supports-Block der richtige Weg. Die langfristige Richtung ist klar: Overlay-Positionierung gehört ins CSS, nicht ins JavaScript. Wer heute mit modernen CSS-APIs arbeitet, baut schlankere, wartbarere und zugänglichere Interfaces.
CSS Anchor Positioning — Das Wichtigste auf einen Blick
Verknüpfung
anchor-name: --name am Auslöser, position-anchor: --name am Overlay. DOM-unabhängige Verknüpfung rein per CSS.
Positionierung
anchor(top/bottom/left/right/center) in Inset-Properties. anchor-size(width) für Breitenübernahme.
Overflow-Handling
@position-try definiert Alternativen. position-try-fallbacks gibt die Reihenfolge vor. Browser wählt automatisch.
Browser-Support
Chrome 125+, Firefox 131+, Safari 18+. Progressive Enhancement via @supports (anchor-name: --x).