CSS Anchor Positioning

Ein Element an einem beliebigen anderen Element ausrichten – egal, wo im DOM es steht. CSS Anchor Positioning erweitert die absolute und fixe Positionierung. Das positionierte Element kann sich an einem anderen Element orientieren, statt nur an seinem positionierten Vorfahren. Das eignet sich besonders für:

  • Tooltips und Popovers, die sich an ihrem Trigger ausrichten
  • Dropdown-Menüs, deren Markup ausserhalb eines begrenzenden Containers liegt
  • Elemente mit gleicher Breite oder Höhe wie ihr Anker
  • Positionen mit Fallbacks, die bei zu wenig Platz automatisch wechseln

POSITIONIERUNG & DOM

Bei position: absolute orientiert sich ein Element normalerweise am nächstgelegenen positionierten Vorfahren. Trigger und Tooltip benötigen deshalb häufig einen gemeinsamen Wrapper. Zudem kann der Tooltip durch overflow: hidden abgeschnitten werden.

Mit CSS Anchor Positioning kann der Tooltip direkt an seinem Trigger ausgerichtet werden, ohne dass beide im selben Wrapper liegen müssen.


Syntax

Für eine einfache Positionierung an einem Anker reichen drei Eigenschaften aus.

  • anchor-nameVergibt dem Anker-Element einen frei wählbaren Namen (wie eine CSS-Variable)
  • position-anchorVerweist beim positionierten Element auf diesen Namen
  • position-areaLegt fest, in welchem Bereich rund um den Anker das Element steht

Anker-Element und Hinweisbox liegen hier absichtlich nicht ineinander verschachtelt im Markup – trotzdem findet die Hinweisbox ihren Anker.

Ich bin der Anker
Ich richte mich am Anker aus

HTML

<span class="anchor">Ich bin der Anker</span>
<div class="tooltip">...</div>

CSS

.anchor {
    anchor-name: --demo-anchor;
}

.tooltip {
    position: absolute;
    position-anchor: --demo-anchor;
    position-area: block-end;
    margin-block-start: 10px;
}

position-anchor

position-anchor legt fest, welches Anker-Element als Bezugspunkt für das positionierte Element dient.

  • normalVerwendet einen impliziten Anker, wenn position-area gesetzt ist
  • noneKein Standard-Anker
  • autoVerwendet einen impliziten Anker, falls einer vorhanden ist
  • --nameVerwendet das Element mit diesem anchor-name
  • match-parentÜbernimmt den Standard-Anker des Elternelements

Bei einem HTML-Popover kann der Button mit popovertarget automatisch als Anker dienen. Ein eigener anchor-name ist dann nicht nötig.


position-area

position-area legt fest, in welchem Bereich rund um den Anker das positionierte Element steht.

  • block-startOberhalb des Ankers
  • block-endUnterhalb des Ankers
  • inline-startVor dem Anker, bei links nach rechts also links
  • inline-endNach dem Anker, bei links nach rechts also rechts
  • centerIm mittleren Bereich des Ankers
  • span-*Erweitert den Bereich über eine angrenzende Spur

Die möglichen Werte lassen sich als 3×3-Raster darstellen. Der Bereich center liegt an der Position des Ankers, die übrigen Bereiche befinden sich rundherum.

Beispiel mit block-end

.anchor {
    anchor-name: --my-anchor;
}

.tooltip {
    position: absolute;
    position-anchor: --my-anchor;
    position-area: block-end;
    margin-block-start: 10px;
}

block-end bedeutet in einer horizontalen Schreibrichtung «unterhalb». Dadurch werden top, left und translate für diese Position nicht benötigt.

Zwei Werte legen die Position in beiden Achsen genauer fest.

Position in zwei Achsen

position-area: block-end inline-start;
position-area: block-start inline-end;
position-area: bottom right;

Logische Werte passen sich der Schreibrichtung an. Physische Angaben wie top, right, bottom und left bleiben dagegen immer gleich.

Bereich erweitern

position-area: block-start span-inline-end;

span-inline-end erweitert den Bereich in Richtung Inline-Ende über eine angrenzende Spur.


Position mit anchor() festlegen

anchor() liest die Position einer Kante oder des Mittelpunkts des Ankers aus. Die Funktion wird als Wert für top, right, bottom oder left verwendet.

  • anchor(top)Obere Kante des Ankers
  • anchor(bottom)Untere Kante des Ankers
  • anchor(left)Linke Kante des Ankers
  • anchor(right)Rechte Kante des Ankers
  • anchor(center)Mittelpunkt des Ankers (horizontal oder vertikal, je nach Eigenschaft)
  • anchor(start)Logische Startkante in der verwendeten Achse
  • anchor(end)Logische Endkante in der verwendeten Achse
  • anchor(inside)Gleiche Seite wie die verwendete Inset-Eigenschaft
  • anchor(outside)Gegenüberliegende Seite der Inset-Eigenschaft

Praxis-Tipp: anchor(center) liefert nur die Koordinate der Mitte – das positionierte Element selbst bleibt an seiner eigenen linken/oberen Kante ausgerichtet. Für echtes Zentrieren zusätzlich translate: -50% 0 (oder 0 -50%) ergänzen, wie im Beispiel oben.

Anchor direkt angeben

Wurde mit position-anchor ein Standard-Anker festgelegt, genügt anchor(bottom). Der Name kann aber auch direkt in der Funktion stehen. So lassen sich in einem Element verschiedene Anker verwenden:

Verschiedene Anker verwenden

.element {
    left: anchor(--first right);
    top: anchor(--second bottom, 0);
}

Der optionale letzte Wert ist ein Fallback. Kann der Anker nicht aufgelöst werden, verwendet top im Beispiel den Wert 0. Auch Prozentwerte sind möglich: anchor(0%) entspricht start, anchor(50%) entspricht center und anchor(100%) entspricht end.


anchor-center

align-self und justify-self richten das positionierte Element innerhalb seines verfügbaren Bereichs aus. anchor-center zentriert es am Standard-Anker.

  • align-selfAusrichtung in der Block-Achse
  • justify-selfAusrichtung in der Inline-Achse
  • anchor-centerZentriert das Element am Standard-Anker

Am Anker zentrieren

.tooltip {
    position: absolute;
    position-anchor: --my-anchor;
    position-area: block-end;
    justify-self: anchor-center;
}

anchor-size()

Mit anchor-size() kann ein positioniertes Element die Breite oder Höhe seines Ankers übernehmen. Das ist beispielsweise für Dropdowns nützlich, die mindestens so breit wie der auslösende Button sein sollen:

  • widthBreite des Ankers
  • heightHöhe des Ankers
  • inlineGrösse in der Inline-Achse des umgebenden Blocks
  • blockGrösse in der Block-Achse des umgebenden Blocks
  • self-inlineInline-Achse des positionierten Elements
  • self-blockBlock-Achse des positionierten Elements
ANKER: 240 PX GLEICHE BREITE MIT anchor-size(width)

Breite des Ankers übernehmen

.dropdown {
    position: absolute;
    position-anchor: --menu-button;
    position-area: block-end;
    min-width: anchor-size(width);
}

Der Anchor-Name und ein Fallbackwert können direkt in der Funktion stehen:

Ankername und Fallback

width: anchor-size(--menu-button width, 12rem);

Ohne Grössenangabe wird die Achse aus der verwendeten Eigenschaft abgeleitet: width: anchor-size() entspricht width: anchor-size(width).


anchor-scope

anchor-name muss nicht auf der ganzen Seite eindeutig sein. Wird eine Komponente mehrfach verwendet, kann anchor-scope denselben Namen auf die jeweilige Komponente begrenzen. So verweist jede Hinweisbox auf den Anker innerhalb ihres eigenen Bereichs:

  • noneKeine Begrenzung, Standardwert
  • --nameBegrenzt den angegebenen Anchor-Namen auf den Bereich
  • allBegrenzt alle Anchor-Namen innerhalb des Bereichs

Namen auf eine Komponente begrenzen

.card {
    anchor-scope: --card-anchor;
}

.card-title {
    anchor-name: --card-anchor;
}

.card-info {
    position: absolute;
    position-anchor: --card-anchor;
    position-area: block-end;
}

Ohne passenden Scope wird bei mehreren sichtbaren Elementen mit demselben Namen der nächste passende Vorfahr verwendet – oder sonst das letzte passende Element im DOM.


position-try-fallbacks

Was passiert, wenn ein anker-positioniertes Element sonst über den Viewport-Rand hinausragen würde? position-try-fallbacks lässt den Browser automatisch eine Alternativ-Position ausprobieren, sobald die erste nicht mehr passt – ohne manuelles max-width- oder Umbruch-Gefrickel.

  • flip-blockKlappt auf die andere Seite der Block-Achse (z. B. topbottom)
  • flip-inlineKlappt auf die andere Seite der Inline-Achse (z. B. leftright)
  • flip-xSpiegelt entlang der horizontalen Achse
  • flip-ySpiegelt entlang der vertikalen Achse
  • flip-startSpiegelt Start- und Endrichtungen diagonal
ANKER Kein Platz unten – ich klappe nach oben.

Position automatisch wechseln

.tooltip {
    position: absolute;
    position-anchor: --my-anchor;
    top: anchor(bottom);
    left: anchor(center);
    position-try-fallbacks: flip-block, flip-inline;
}

Praxis-Tipp: Der Browser übernimmt die Berechnung, welche Seite gerade genug Platz hat – eleganter als das Overflow-Problem selbst mit fixen Grössenangaben abzufangen.

position-try-order

Standardmässig prüft der Browser die Fallbacks in der angegebenen Reihenfolge. position-try-order kann stattdessen die Variante mit dem meisten verfügbaren Platz bevorzugen:

  • normalReihenfolge aus position-try-fallbacks
  • most-widthVariante mit der grössten Breite zuerst
  • most-heightVariante mit der grössten Höhe zuerst
  • most-inline-sizeGrösster Platz in der Inline-Achse
  • most-block-sizeGrösster Platz in der Block-Achse

Variante mit dem meisten Platz

.tooltip {
    position-try-fallbacks: flip-block, flip-inline;
    position-try-order: most-height;
}

Eigene Fallbacks mit @position-try

Reichen die eingebauten Flip-Varianten nicht aus, definiert @position-try eine eigene Alternativposition. Der frei gewählte Name wird anschliessend in position-try-fallbacks verwendet:

Eigene Alternativposition

@position-try --above {
    position-area: block-start;
    max-height: 40vh;
}

.tooltip {
    position-area: block-end;
    position-try-fallbacks: --above, flip-inline;
}

Innerhalb von @position-try sind Eigenschaften für Position, Abstände, Grösse, Ausrichtung, position-anchor und position-area erlaubt.


position-visibility

position-visibility blendet ein anker-positioniertes Element abhängig von seinem Anker oder dem verfügbaren Platz aus:

  • alwaysImmer anzeigen
  • anchor-validAusblenden, wenn der Anker nicht aufgelöst werden kann
  • anchor-visibleAusblenden, wenn der Anker nicht sichtbar oder vollständig abgeschnitten ist
  • no-overflowAusblenden, wenn das Element trotz Fallback überläuft

Abhängig von Anker und Platz ausblenden

.tooltip {
    position-visibility: anchor-visible no-overflow;
}

Mehrere Bedingungen lassen sich kombinieren. anchor-visible ist der Standardwert.


Beispiel mit mehreren Ankern

Bei mehreren Anker-Elementen erhält in diesem Beispiel jedes Anker-Tooltip-Paar einen eigenen anchor-name. So lässt sich jedes Tooltip eindeutig dem gewünschten Anker zuordnen. :nth-child() adressiert dabei jedes Paar einzeln. Die Tooltips sind hier zusätzlich standardmässig unsichtbar und werden bei Hover eingeblendet – geh mit der Maus über ein Icon. Auf Touchgeräten bleiben die Hinweise sichtbar.

A
B
C
Icon A
Icon B
Icon C

Anker und Tooltips zuordnen

.icon:nth-child(1) { anchor-name: --icon-1; }
.icon:nth-child(2) { anchor-name: --icon-2; }
.icon:nth-child(3) { anchor-name: --icon-3; }

.icon-tip:nth-child(4) { position-anchor: --icon-1; }
.icon-tip:nth-child(5) { position-anchor: --icon-2; }
.icon-tip:nth-child(6) { position-anchor: --icon-3; }

Für den Hover-Effekt reicht CSS – Icon und Tooltip sind zwar nicht verschachtelt, aber Geschwister im DOM. Der allgemeine Geschwister-Kombinator ~ (im Gegensatz zum direkten +) matcht dabei jedes spätere Geschwister, nicht nur das unmittelbar folgende:

Tooltip bei Hover einblenden

.icon:nth-child(1):hover ~ .icon-tip:nth-child(4) {
    opacity: 1;
}

Semantik & Barrierefreiheit

Anchor Positioning erzeugt nur eine visuelle Beziehung. Es macht aus einem Element weder automatisch einen Button noch verknüpft es Tooltip und Anker für assistive Technologien. Die semantische Beziehung muss deshalb weiterhin mit passenden HTML-Elementen und – falls nötig – ARIA-Attributen hergestellt werden.


Browser-Support

Die Unterstützung einzelner Funktionen von CSS Anchor Positioning kann sich je nach Browser unterscheiden. Mit @supports lässt sich prüfen, ob anchor-name unterstützt wird. Für andere Browser bleibt eine klassische Positionierung als Fallback.

Unterstützung mit @supports prüfen

@supports (anchor-name: --x) {
  .tooltip {
    position-anchor: --my-anchor;
    position-area: block-end;
  }
}

Kurz gesagt

  • anchor-name benennt den Anker, position-anchor verbindet das positionierte Element mit ihm.
  • position-area platziert ein Element in einem Bereich rund um den Anker.
  • anchor() ermöglicht die genaue Positionierung an Kanten oder Mittelpunkt.
  • anchor-center richtet ein positioniertes Element am Anker aus.
  • anchor-size() übernimmt die Breite oder Höhe des Ankers.
  • anchor-scope begrenzt wiederverwendete Ankernamen auf einen Bereich.
  • position-try-fallbacks und @position-try definieren Alternativen bei zu wenig Platz.
  • position-visibility blendet ein positioniertes Element bei Bedarf aus.

NurseVerwandte Themen

  • CSS Position – Elemente relativ, absolut, fixiert oder sticky positionieren.
  • HTML Popover – Popovers öffnen, schliessen und zugänglich umsetzen.
  • CSS Overflow – Überlaufende Inhalte begrenzen oder scrollbar machen.