Ich erinnere mich noch genau an das erste Mal, als ich Popper.js in ein Projekt eingebaut habe – das war zu Bootstrap 4 Zeiten, als es plötzlich als Pflicht-Dependency dabei war. Ein Tooltip sollte an einem Button haften, nicht am Viewport-Rand abgeschnitten werden und beim Scrollen mitlaufen. Drei Dependencies, 40 KB Bundle-Größe, und ein popper.update()-Aufruf in fünf verschiedenen Event-Handlern – für ein einzelnes schwebendes Element.
Das war der Stand der Dinge. Bis jetzt.
Seit Januar 2026 ist CSS Anchor Positioning in allen modernen Browsern als Baseline-Feature angekommen. Was das bedeutet: Tooltips, Dropdowns, Kontextmenüs und Popovers lassen sich ab sofort ohne JavaScript positionieren – deklarativ, performant, und mit automatischen Fallback-Positionen wenn der Platz knapp wird.
Das Problem das Popper.js gelöst hat – und warum CSS es jetzt selbst kann
Früher war das Kernproblem folgendes: CSS position: absolute positioniert ein Element relativ zu seinem nächsten positionierten Vorfahren im DOM. Ein Tooltip, der neben einem Button erscheinen soll, muss also entweder ein Kind dieses Buttons sein – oder du brichst mit JavaScript aus dem DOM-Flow aus.
Genau das haben Popper.js und dessen Nachfolger Floating UI gemacht: DOM-Element in ein Portal rendern, per JavaScript die Koordinaten des Ziel-Elements berechnen, bei jedem Scroll und Resize neu kalkulieren, und Overflow-Konflikte abfangen. Funktioniert – aber es ist konzeptionell Flickwerk.
CSS Anchor Positioning löst das Problem auf Spec-Ebene. Ein Element kann nun direkt an ein anderes Element gebunden werden, egal wo beide im DOM stehen.
Die drei Kernkonzepte
1. Anchor definieren: anchor-name
Jedes Element kann mit anchor-name zum Anker werden:
.help-button {
anchor-name: --help-trigger;
}
Der doppelte Bindestrich ist kein Zufall – Anchor-Namen folgen der gleichen Syntax wie CSS Custom Properties. Das macht sie per se namespaced und verhindert Kollisionen.
2. Positioniertes Element verknüpfen: position-anchor
Das schwebende Element bekommt dann eine Verknüpfung:
.tooltip {
position: absolute;
position-anchor: --help-trigger;
}
Ab hier weiß der Browser: dieses Element ist an --help-trigger gebunden.
3. Position setzen: anchor() und position-area
Jetzt kommt die eigentliche Positionierung. Es gibt zwei Wege:
Weg 1 – position-area (einfacher, für die meisten Fälle):
.tooltip {
position: absolute;
position-anchor: --help-trigger;
position-area: top center;
}
position-area nimmt ein 3×3-Raster rund um den Anker und platziert das Element in einer der neun Zonen: top left, bottom right, center, etc.
Weg 2 – anchor() Funktion (präziser, für komplexere Layouts):
.tooltip {
position: absolute;
position-anchor: --help-trigger;
bottom: calc(anchor(top) + 8px);
left: anchor(left);
}
anchor(top) gibt dir den exakten Y-Wert der oberen Kante des Anker-Elements zurück – als <length>, die du in calc() verwenden kannst.
Das Killer-Feature: Automatische Fallback-Positionen
Hier trennt sich CSS Anchor Positioning wirklich von händischer Positionierung. Mit position-try-fallbacks gibst du dem Browser eine Liste alternativer Positionen – und er wählt automatisch die erste, die nicht abgeschnitten wird:
.tooltip {
position: absolute;
position-anchor: --help-trigger;
position-area: top center;
position-try-fallbacks: bottom center, right center, left center;
}
Wenn top center am Viewport-Rand abgeschnitten wäre, probiert der Browser bottom center – und so weiter. Das war früher genau der Part, für den man eine Library brauchte.
Ein vollständiges Tooltip-Beispiel
<button class="help-button" popovertarget="tooltip-1">
Hilfe
</button>
<div id="tooltip-1" class="tooltip" popover>
Hier steht der Hilfetext.
</div>
.help-button {
anchor-name: --help-trigger;
}
.tooltip {
position: absolute;
position-anchor: --help-trigger;
position-area: top center;
position-try-fallbacks: bottom center, right center;
margin-block-end: 8px;
background: #1a1a2e;
color: white;
padding: 0.5rem 0.75rem;
border-radius: 4px;
width: max-content;
max-width: 240px;
}
Kombiniert mit dem nativen popover-Attribut (das mittlerweile ebenfalls Baseline ist) bekommst du Toggle-Verhalten gratis dazu – kein JavaScript, kein Event-Listener, kein State-Management.
Was ist mit dem Overflow-Problem?
Wer schon mal mit overflow: hidden auf einem Container und einem absolut positionierten Kind gearbeitet hat, kennt den Schmerz: das Element wird abgeschnitten, obwohl es visuell “außerhalb” des Containers stehen soll.
CSS Anchor Positioning löst das nicht magisch – aber in Kombination mit popover schon. Elemente mit popover werden in der sogenannten Top Layer des Browsers gerendert, also komplett außerhalb des normalen Stacking-Kontexts. Kein z-Index-Krieg, kein Overflow-Problem.
Browser-Support: Seit Januar 2026 Baseline
Seit Januar 2026 funktioniert CSS Anchor Positioning in allen aktuellen Browsern. Für ältere Browser oder spezifische Teilfeatures gibt es den CSS Anchor Positioning Polyfill von OddBird – ein JavaScript-Fallback, der die API nachbaut.
Eine Einschränkung bleibt: Bestimmte Teilaspekte der Spezifikation haben noch unterschiedliche Unterstützung – Firefox hat etwa mit dem ::moz-range-thumb Pseudo-Element als Anker noch einen bekannten Bug. Für den typischen Anwendungsfall (Tooltips, Dropdowns, Popovers) ist das kein Problem.
Wann lohnt sich die Migration?
Wenn du heute noch Popper.js oder Floating UI einsetzt, lohnt sich ein genauer Blick auf dein Setup:
Direkter Ersatz möglich wenn du Tooltips, einfache Dropdowns, oder Popovers mit festen Positionen und Fallback-Logik baust. Das ist der Sweet Spot von CSS Anchor Positioning.
JavaScript bleibt nötig für hover-getriggerte Tooltips mit Timing-Logik (das Interest Invoker API ist gerade in Entwicklung und wird das langfristig lösen), oder für dynamisch berechnete Positionen die von externen Daten abhängen.
Behalte die Library wenn du Vue/React-Komponenten einsetzt, die Floating UI intern nutzen (z.B. Headless UI, Radix, Melt UI) – die werden ihre Implementierungen schrittweise selbst migrieren.
Code Beispiele
See the Pen Untitled by Tobeworks (@tobeworks) on CodePen.
Fazit
CSS Anchor Positioning ist kein “nice to have”. Es ist die native Lösung für ein Problem, das wir seit Jahren mit immer dickeren JavaScript-Schichten gepflastert haben. Die API ist klar, die Browser-Unterstützung ist da, und das Zusammenspiel mit dem popover-Attribut macht viele klassische UI-Pattern zum ersten Mal wirklich wartbar.
Ich setze es in neuen Projekten bereits ein. Ob ich Popper.js in bestehenden Projekten aktiv rausmigriere – kommt auf den Aufwand an. Aber in neuen Komponenten lautet die Default-Antwort auf “floating element neben einem anderen Element” jetzt: kein npm install mehr.
Kommentare