CSS Anchor Positioning & Popover API: Kein JS mehr für Popups im Jahr 2026
前端工程
CSS Anchor Positioning: Die „Emanzipationsproklamation" für Frontend-Entwickler
Jeder Frontend-Entwickler hat diesen Schmerz erlebt: JS zur Berechnung von Tooltip-Positionen verwenden, Boundary-Overflow behandeln, Scroll- und Resize-Events abhören... Jetzt kann CSS all dies nativ erledigen.
Historischer Rückblick: 2016 nutzten wir Popper.js, 2020 Floating UI, und 2026 haben wir endlich natives CSS-Anchor-Positioning. Nach 10 Jahren ist Popup-Positionierung keine JS-Aufgabe mehr.
Evolution von JS-Positionierung zu CSS-Positionierung
2016 jQuery offset() + manuelle Berechnung
Neuberechnung bei jedem Scroll/Resize
2020 Floating UI / Popper.js
Auto-Flip, Offset, Boundary-Erkennung
Aber erfordert immer noch JS-Init und Destroy
2024 CSS Anchor Positioning (Chrome 125+)
Reine CSS-deklarative Positionierung
Browser verarbeitet Grenzen und Scrolling nativ
2026 Anchor Positioning + Popover API
Reine CSS-Popups: Zero-JS-Toggle, Zero-JS-Positionierung
Vollständige deklarative Popup-Lösung
anchor-name und position-anchor
Grundlegende Verwendung
<div class="card">
<button class="trigger">Weitere Aktionen</button>
<div class="dropdown">Dropdown-Inhalt</div>
</div>
.trigger {
anchor-name: --my-anchor;
}
.dropdown {
position: fixed;
position-anchor: --my-anchor;
top: anchor(bottom);
left: anchor(left);
}
anchor()-Funktionsreferenz
.tooltip {
position: fixed;
position-anchor: --trigger-anchor;
/* Relativ zu Anker-Kanten */
top: anchor(bottom);
bottom: anchor(top);
left: anchor(left);
right: anchor(right);
/* Anker-Mittelpunkte */
left: anchor(50%);
top: anchor(50%);
/* Mit Versatz */
top: calc(anchor(bottom) + 8px);
left: calc(anchor(left) - 4px);
}
position-area: Neun-Feld-Positionierung
Neun-Feld-Syntax
┌─────────────┬─────────────┬─────────────┐
│ top left │ top center│ top right │
│ │ │ │
├─────────────┼─────────────┼─────────────┤
│ center left │ center │ center right│
│ │ │ │
├─────────────┼─────────────┼─────────────┤
│ bottom left │bottom center│ bottom right│
│ │ │ │
└─────────────┴─────────────┴─────────────┘
.tooltip-below {
position-area: bottom center;
}
.tooltip-right {
position-area: center right;
}
.dropdown-below-left {
position-area: bottom left;
}
position-fallback und mehrstufige Fallback-Strategie
Boundary-Overflow Auto-Flip
.dropdown {
position: fixed;
position-anchor: --trigger;
/* Bevorzugt: unterhalb des Ankers */
top: anchor(bottom);
left: anchor(left);
position-fallback: --dropdown-fallback;
}
@position-fallback --dropdown-fallback {
/* Fallback 1: oberhalb des Ankers */
@try {
bottom: anchor(top);
left: anchor(left);
}
/* Fallback 2: unterhalb des Ankers, rechtsbündig */
@try {
top: anchor(bottom);
right: anchor(right);
}
/* Fallback 3: oberhalb des Ankers, rechtsbündig */
@try {
bottom: anchor(top);
right: anchor(right);
}
}
Popover API: Native Popover-Schicht
Grundlegende Verwendung
<button popovertarget="my-popover">Popover öffnen</button>
<div id="my-popover" popover>
<p>Dies ist nativer Popover-Inhalt</p>
<button popovertarget="my-popover" popovertargetaction="hide">Schließen</button>
</div>
[popover] {
position: fixed;
inset: unset;
margin: 0;
padding: 16px;
border: 1px solid #e5e7eb;
border-radius: 8px;
background: white;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}
Popover + Anchor Kombination
<button class="menu-trigger" popovertarget="menu-popover">Menü</button>
<div id="menu-popover" popover class="menu-dropdown">
<a href="/profile">Profil</a>
<a href="/settings">Einstellungen</a>
<a href="/logout">Abmelden</a>
</div>
.menu-trigger {
anchor-name: --menu-anchor;
}
.menu-dropdown {
position-anchor: --menu-anchor;
position-area: bottom left;
margin: 4px;
}
anchor-size(): Auto-Größenanpassung basierend auf dem Anker-Element
.trigger {
anchor-name: --select-anchor;
}
.select-dropdown {
position: fixed;
position-anchor: --select-anchor;
top: anchor(bottom);
left: anchor(left);
/* Dropdown-Breite folgt dem Trigger-Button */
width: anchor-size(width);
/* Oder Mindestbreite festlegen */
min-width: anchor-size(width);
}
Praxis: Gängige UI-Komponenten in reinem CSS
Tooltip
<span class="tooltip-trigger" tabindex="0">
Hilfe
<span class="tooltip-content" role="tooltip">Dies ist ein Hilfe-Tooltip</span>
</span>
.tooltip-trigger {
anchor-name: --tt-anchor;
position: relative;
cursor: help;
text-decoration: underline dotted;
}
.tooltip-content {
position: fixed;
position-anchor: --tt-anchor;
position-area: top center;
margin: 8px;
padding: 6px 10px;
background: #1f2937;
color: white;
border-radius: 4px;
font-size: 13px;
white-space: nowrap;
pointer-events: none;
opacity: 0;
transition: opacity 0.15s;
position-fallback: --tt-fallback;
}
.tooltip-trigger:hover .tooltip-content,
.tooltip-trigger:focus .tooltip-content {
opacity: 1;
}
@position-fallback --tt-fallback {
@try { position-area: bottom center; }
@try { position-area: center right; }
@try { position-area: center left; }
}
Dropdown-Menü
<button class="dropdown-trigger" popovertarget="dd-menu">
Optionen ▾
</button>
<div id="dd-menu" popover class="dropdown-menu">
<button class="dropdown-item">Bearbeiten</button>
<button class="dropdown-item">Kopieren</button>
<button class="dropdown-item">Löschen</button>
</div>
.dropdown-trigger {
anchor-name: --dd-anchor;
}
.dropdown-menu {
position-anchor: --dd-anchor;
position-area: bottom left;
margin: 4px;
width: anchor-size(width);
min-width: 160px;
padding: 4px;
border-radius: 8px;
background: white;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
position-fallback: --dd-fallback;
}
.dropdown-item {
display: block;
width: 100%;
padding: 8px 12px;
border: none;
background: none;
text-align: left;
border-radius: 4px;
cursor: pointer;
}
.dropdown-item:hover {
background: #f3f4f6;
}
@position-fallback --dd-fallback {
@try { position-area: top left; }
}
Vergleich mit Floating UI/Popper.js
| Dimension | CSS Anchor + Popover | Floating UI |
|---|---|---|
| JS-Abhängigkeit | Zero JS | 12KB gzip |
| Leistung | Browser-nativ | JS-Berechnung |
| Deklarativ | CSS-deklarativ | JS-imperativ |
| Boundary-Flip | position-fallback | flip()-Middleware |
| Versatz | margin/anchor() | offset()-Middleware |
| Pfeil | CSS-Pseudo-Element | SVG/HTML-Element |
| Virtuelle Elemente | Nicht unterstützt | Unterstützt |
| Dynamischer Inhalt | Auto-Follow | Benötigt update() |
| Browser-Support | Chrome 125+ | Alle Browser |
| SSR-freundlich | Vollständig freundlich | Benötigt Client-JS |
Wann Sie noch JS-Bibliotheken benötigen
Szenarien, die noch Floating UI erfordern:
1. Ältere Browser unterstützen müssen (Safari < 17.5, Firefox < 131)
2. Virtuelle Element-Positionierung benötigen (Cursor-Position folgen)
3. Komplexe Middleware-Ketten benötigen (autoUpdate, size, hide)
4. React/Vue-deklarative Wrapper-Anforderungen
Szenarien, in denen CSS Anchor funktioniert:
1. Tooltip, Dropdown, Popover und andere Standard-Popups
2. Nur moderne Browser unterstützen müssen
3. Zero-JS-Abhängigkeit anstreben
4. Leistungs-sensitive Szenarien
Browserkompatibilität und Polyfill
Support-Status
| Browser | Anchor Positioning | Popover API |
|---|---|---|
| Chrome 125+ | ✅ | ✅ |
| Edge 125+ | ✅ | ✅ |
| Safari 17.5+ | ✅ | ✅ |
| Firefox 131+ | ✅ | ✅ |
| iOS Safari 17.5+ | ✅ | ✅ |
Polyfill-Lösungen
<script src="https://cdn.jsdelivr.net/npm/@oddbird/css-anchor-positioning@0.3.0/dist/css-anchor-positioning.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@oddbird/popover-polyfill@0.4.0/dist/popover.min.js"></script>
Kombination mit @starting-style für Popup-Animationen
[popover] {
opacity: 0;
transform: translateY(-8px) scale(0.95);
transition: opacity 0.2s, transform 0.2s, display 0.2s allow-discrete;
overlay: none;
}
[popover]:popover-open {
opacity: 1;
transform: translateY(0) scale(1);
overlay: auto;
}
@starting-style {
[popover]:popover-open {
opacity: 0;
transform: translateY(-8px) scale(0.95);
}
}
Zusammenfassung
- CSS Anchor Positioning ist die ultimative Lösung für Popup-Positionierung — Zero JS, deklarativ, browser-nativ
- Die Popover API macht Popup-Toggling ebenfalls Zero JS — das popovertarget-Attribut erledigt es in einer Zeile
- position-fallback löst Boundary-Overflow — Keine JS-Berechnung für Flipping mehr
- Alle wichtigen Browser unterstützen es 2026 — Sicher in der Produktion einsetzbar
Nach 10 Jahren ist Popup-Positionierung endlich dorthin zurückgekehrt, wo sie hingehört: CSS. Dies ist keine schrittweise Verbesserung — es ist ein Paradigmenwechsel, genau wie Flexbox Float-Layouts abgelöst hat.
Probiere diese browser-lokalen Tools aus — keine Registrierung erforderlich →
#CSS锚点定位#Anchor Positioning#Popover API#弹出层#CSS