Verwendung der CSS-Ankerpositionierung
Das CSS-Ankerpositionierungsmodul definiert Funktionen, die es ermöglichen, Elemente miteinander zu verknüpfen. Elemente können als Ankerelemente und ankerpositionierte Elemente definiert werden. Ankerpositionierte Elemente können an Ankerelemente gebunden werden. Die Größe und Position der ankerpositionierten Elemente kann dann relativ zur Größe und Position der Ankerelemente eingestellt werden, an die sie gebunden sind.
Die CSS-Ankerpositionierung bietet auch Mechanismen, um mehrere alternative Positionen für ein ankerpositioniertes Element festzulegen, die nur in CSS verwendet werden. Wenn ein Tooltip beispielsweise an ein Formularfeld gebunden ist, aber in den Standardpositionseinstellungen außerhalb des Bildschirms angezeigt würde, kann der Browser versuchen, ihn in einer anderen vorgeschlagenen Position zu rendern, damit er auf dem Bildschirm platziert wird, oder alternativ ganz ausblenden, wenn gewünscht.
Dieser Artikel erklärt die grundlegenden Konzepte der Ankerpositionierung und wie man die Assoziations-, Positionierungs- und Größenänderungsfunktionen des Moduls auf einer grundlegenden Ebene nutzt. Wir haben Links zu Referenzseiten mit zusätzlichen Beispielen und Syntaxdetails für jedes unten diskutierte Konzept beigefügt. Informationen zum Festlegen alternativer Positionen und zum Ausblenden von ankerpositionierten Elementen finden Sie im Leitfaden zu Rückfalleinstellungen und bedingtem Ausblenden bei Überlauf.
Grundlegende Konzepte
Es ist sehr üblich, ein Element an ein anderes zu binden. Zum Beispiel:
- Fehlermeldungen, die neben Formularsteuerelementen erscheinen.
- Tooltips oder Infoboxen, die neben einem UI-Element erscheinen, um weitere Informationen bereitzustellen.
- Einstellungs- oder Optionsdialoge, die aufgerufen werden können, um UI-Elemente schnell zu konfigurieren.
- Dropdown- oder Popover-Menüs, die neben einer zugehörigen Navigationsleiste oder Schaltfläche erscheinen.
Moderne Benutzeroberflächen erfordern häufig, dass einige Inhalte — oft wiederverwendbar und dynamisch generiert — relativ zu einem Ankerelement platziert werden. Solche Anwendungsfälle zu erstellen, wäre ziemlich einfach, wenn das zu bindende Element (auch bekannt als Ankerelement) immer an derselben Stelle in der Benutzeroberfläche wäre und das gebundene Element (auch bekannt als ankerpositioniertes Element oder einfach positioniertes Element) immer direkt davor oder danach in der Quellreihenfolge platziert werden könnte. In der Praxis sind die Dinge jedoch selten so einfach.
Der Standort von positionierten Elementen relativ zu ihrem Ankerelement muss beibehalten und angepasst werden, wenn sich das Ankerelement bewegt oder anderweitig konfiguriert wird (z. B. durch Scrollen, Ändern der Viewportgröße, Ziehen und Ablegen usw.). Wenn sich beispielsweise ein Element wie ein Formularfeld in der Nähe des Randes des Viewports befindet, kann sein Tooltip außerhalb des Bildschirms enden. In der Regel möchten Sie den Tooltip an sein Formularsteuerelement binden und sicherstellen, dass der Tooltip so lange vollständig sichtbar auf dem Bildschirm bleibt, wie das Formularfeld sichtbar ist, und den Tooltip bei Bedarf automatisch verschieben. Möglicherweise haben Sie dies als Standardverhalten in Ihrem Betriebssystem bemerkt, wenn Sie Kontextmenüs mit der rechten Maustaste (Strg + Klicken) auf Ihrem Desktop oder Laptop verwenden.
Historisch gesehen erforderte die Assoziierung eines Elements mit einem anderen Element und das dynamische Ändern der Position und Größe eines positionierten Elements basierend auf der Position eines Ankers JavaScript, was Komplexität und Leistungsprobleme verursachte. Es war auch nicht garantiert, dass es in allen Situationen funktionierte. Die im CSS-Ankerpositionierungsmodul definierten Funktionen ermöglichen es, solche Anwendungsfälle performanter und deklarativer mit CSS (und HTML) anstelle von JavaScript zu implementieren.
Assoziierung von Anker- und positionierten Elementen
Um ein Element mit einem Anker zu assoziieren, müssen Sie zuerst deklarieren, welches Element der Anker ist, und dann angeben, welches(n) positionierte Element(e) mit diesem Anker assoziiert werden soll(en). Dies schafft eine Ankerreferenz zwischen den beiden. Diese Assoziation kann explizit über CSS oder implizit erstellt werden.
Explizite CSS-Ankerassoziation
Um ein Element als Anker mit CSS zu deklarieren, müssen Sie ihm einen Ankernamen über die anchor-name-Eigenschaft zuweisen. Der Ankname muss ein <dashed-ident> sein. In diesem Beispiel setzen wir die Breite des Ankers auch auf fit-content, um einen kleinen quadratischen Anker zu erhalten, was den Ankereffekt besser demonstriert.
.anchor {
anchor-name: --my-anchor;
width: fit-content;
}
Um ein Element in ein ankerpositioniertes Element zu konvertieren, sind zwei Schritte erforderlich: Es muss absolut oder fix positioniert mit der position-Eigenschaft sein. Das positionierte Element hat dann seine position-anchor-Eigenschaft auf den Wert der anchor-name-Eigenschaft des Ankerelements gesetzt:
.infobox {
position: fixed;
position-anchor: --my-anchor;
}
Wir werden das obige CSS auf folgendes HTML anwenden:
<div class="anchor">⚓︎</div>
<div class="infobox">
<p>This is an information box.</p>
</div>
Dies wird wie folgt gerendert:
Der Anker und die Infobox sind nun assoziiert, aber im Moment müssen Sie uns darauf vertrauen. Sie sind noch nicht aneinander gebunden — wenn Sie den Anker positionieren und ihn an eine andere Stelle auf der Seite verschieben würden, würde er sich alleine bewegen und die Infobox an derselben Stelle lassen. Sie werden das tatsächliche Verbinden in Aktion sehen, wenn wir uns Elemente basierend auf der Ankerposition positionieren ansehen.
Implizite Ankerassoziation
In einigen Fällen wird aufgrund der semantischen Natur ihrer Beziehung eine implizite Ankerreferenz zwischen zwei Elementen erstellt:
- Wenn Sie die Popover-API verwenden, um ein Popover mit einem Steuerelement zu assoziieren, wird eine implizite Ankerreferenz zwischen den beiden erstellt. Dies kann geschehen, wenn:
- Ein Popover mit einem Steuerelement unter Verwendung der Attribute
popovertargetundidodercommandforundiddeklarativ assoziiert wird. - Eine Popover-Aktion wie
showPopover()programmatisch mit einem Steuerelement unter Verwendung dersource-Option assoziiert wird.
- Ein Popover mit einem Steuerelement unter Verwendung der Attribute
- Ein
<select>-Element und seine Dropdown-Auswahl sind über dieappearance-Eigenschaft mit dembase-select-Wert in die anpassbare Auswahl Funktionalität aufgenommen. In diesem Fall wird eine implizite Popover-Invoker-Beziehung zwischen den beiden erstellt, was auch bedeutet, dass sie eine implizite Ankerreferenz haben.
Hinweis: Die oben genannten Methoden assoziieren einen Anker mit einem Element, sind jedoch noch nicht miteinander verbunden. Um sie zusammenzubinden, muss das positionierte Element relativ zu seinem Anker positioniert werden, was mit CSS erfolgt.
Entfernen einer Ankerassoziation
Wenn Sie eine zuvor zwischen einem Ankerelement und einem positionierten Element hergestellte explizite Ankerassoziation entfernen möchten, können Sie eines der folgenden tun:
- Setzen Sie den Wert der
anchor-name-Eigenschaft des Ankers aufnoneoder auf ein anderes<dashed-ident>, wenn Sie möchten, dass ein anderes Element an ihn gebunden wird. - Setzen Sie die
position-anchor-Eigenschaft des positionierten Elements aufnoneoder auf einen nicht existierenden Ankernamen im aktuellen Dokument, wie beispielsweise--not-an-anchor-name.
Im Falle von impliziten Ankerassoziationen müssen Sie die zweite Methode verwenden — die erste Methode funktioniert nicht. Dies liegt daran, dass die Assoziation intern gesteuert wird und Sie den anchor-name nicht über CSS entfernen können.
Um beispielsweise zu verhindern, dass ein anpassbares <select>-Element an das <select>-Element selbst gebunden wird, könnten Sie folgende Regel verwenden:
::picker(select) {
position-anchor: none;
}
Anker-Skopierung
Wenn mehreren Ankerelementen derselbe anchor-name-Wert zugewiesen wird und ein positioniertes Element diesen Namen als seinen position-anchor-Eigenschaftswert hat, wird das positionierte Element mit dem letzten Ankerelement in der Quellreihenfolge mit diesem anchor-name-Wert assoziiert.
Wenn ein Dokument beispielsweise mehrere wiederholte Komponenten enthält, die jeweils ein positioniertes Element mit einem Anker verbunden haben, werden alle positionierten Elemente an den letzten Anker auf der Seite gebunden, es sei denn, jede Komponente verwendet einen anderen Ankernamen. Dies ist wahrscheinlich nicht das gewünschte Verhalten.
Die anchor-scope-Eigenschaft kann dieses Problem lösen, indem die Sichtbarkeit oder der "Geltungsbereich" eines anchor-name-Wertes auf einen bestimmten Teilbaum beschränkt wird. Das Ergebnis ist, dass jedes positionierte Element nur an ein Element innerhalb desselben Teilbaums des Elements, das den Geltungsbereich auf ihm gesetzt hat, gebunden werden kann.
anchor-scope: allsetzt den Geltungsbereich so, dass jedeanchor-name-Werte, die im Teilbaum gesetzt sind, nur von positionierten Elementen innerhalb desselben Teilbaums gebunden werden können.anchor-scope: --my-anchor, --my-anchor2setzt den Geltungsbereich so, dass die angegebenenanchor-name-Werte, wenn sie im Teilbaum gesetzt sind, nur von positionierten Elementen in demselben Teilbaum gebunden werden können.anchor-scope: noneist der Standardwert; er gibt an, dass kein Anker-Skopierung gesetzt ist.
Angenommen, Sie haben mehrere Anker und ankerpositionierte <div>-Elemente innerhalb von <section>-Containern:
<section class="scoped">
<div class="anchor">⚓︎</div>
<div class="positioned">Positioned 1</div>
</section>
<section class="scoped">
<div class="anchor">⚓︎</div>
<div class="positioned">Positioned 2</div>
</section>
<section class="scoped">
<div class="anchor">⚓︎</div>
<div class="positioned">Positioned 3</div>
</section>
Wir wandeln jedes anchor-<div> in ein Ankerelement um, indem wir ihnen einen anchor-name-Wert von --my-anchor geben. Dann positionieren wir jedes positioned-<div> relativ zu einem Element mit dem --my-anchor-Ankernamen, indem wir ihnen absolute Positionierung, einen position-anchor-Wert von --my-anchor und einen position-area-Wert von right geben. Schließlich setzen wir den Ankergeltungsbereich jedes <section>-Containers mit anchor-scope: --my-anchor:
.anchor {
anchor-name: --my-anchor;
}
.positioned {
position: absolute;
position-anchor: --my-anchor;
position-area: right;
}
.scoped {
anchor-scope: --my-anchor;
}
Dies führt zu folgendem Positionierungsverhalten:
Jedes positionierte Element wird relativ zum Anker innerhalb desselben <section>-Elements positioniert. Das liegt daran, dass jedes <section>-Element einen anchor-scope von --my-anchor gesetzt hat; positionierte Elemente innerhalb jedes skopierten Containers können daher nur relativ zu my-anchor-Ankern innerhalb desselben Containers positioniert werden.
Wenn wir nicht anchor-scope: --my-anchor auf die Container setzen würden, würden alle positionierten Elemente relativ zum letzten Anker auf der Seite positioniert.
Elemente relativ zu ihrem Anker positionieren
Wie wir bereits gesehen haben, bringt es nicht viel, ein positioniertes Element mit einem Anker zu assoziieren, ohne es weiter zu bearbeiten. Unser Ziel ist es, das positionierte Element relativ zu seinem assoziierten Ankerelement zu platzieren. Dies geschieht entweder durch das Festlegen eines CSS-anchor()-Funktionen auf einer Inset-Eigenschaft, das Festlegen eines position-area oder indem das positionierte Element mit dem anchor-center Platzierungswert zentriert wird.
Hinweis: Die CSS-Ankerpositionierung bietet auch Mechanismen zur Angabe von Rückfallpositionen, wenn die Standardposition des positionierten Elements dazu führt, dass es aus dem Viewport ragt. Weitere Informationen finden Sie im Leitfaden zu Rückfalleinstellungen und bedingtem Ausblenden.
Hinweis:
Das Ankerelement muss ein sichtbarer DOM-Node sein, damit die Assoziation und die Positionierung funktionieren. Wenn es ausgeblendet ist (z. B. über display: none), wird das positionierte Element relativ zu seinem nächstgelegenen positionierten Vorfahren positioniert. Wir erläutern, wie ein ankerpositioniertes Element ausgeblendet wird, wenn sein Anker verschwindet, im Bedingten Ausblenden mit position-visibility.
Verwendung von Inset-Eigenschaften mit anchor()-Funktionswerten
Konventionelle absolut und fix positionierte Elemente werden explizit durch das Setzen von <length>- oder <percentage>-Werten auf Inset-Eigenschaften positioniert. Bei position: absolute ist dieser Inset-Positionswert ein absoluter Abstand relativ zu den Kanten des nächstgelegenen positionierten Vorfahren. Bei position: fixed ist der Inset-Positionswert ein absoluter Abstand relativ zum Viewport.
Die CSS-Ankerpositionierung ändert dieses Paradigma, indem es ankerpositionierten Elementen ermöglicht wird, relativ zu den Kanten ihrer zugehörigen Anker platziert zu werden. Das Modul definiert die anchor()-Funktion, die ein gültiger Wert für jede der Inset-Eigenschaften ist. Bei Verwendung setzt die Funktion den Inset-Positionswert als absoluten Abstand relativ zum Ankerelement, indem das Ankerelement, die Seite des Ankerelements, zu der das positionierte Element relativ platziert wird, und der Abstand von dieser Seite definiert werden.
Die Komponenten der Funktion sehen so aus:
anchor(<anchor-name> <anchor-side>, <fallback>)
<anchor-name>-
Der
anchor-name-Eigenschaftswert des Ankerelements, relativ zu dem die Seite des Elements positioniert werden soll. Dies ist ein<dashed-ident>-Wert. Wenn er weggelassen wird, wird der Standardanker des Elements verwendet. Dies ist der Anker, der in seinerposition-anchor-Eigenschaft oder durch das nicht-standardisierteanchor-HTML-Attribut referenziert wird.Hinweis: Das Angeben eines
<anchor-name>positioniert das Element relativ zu diesem Anker, bietet jedoch keine Elementassoziation. Während Sie die Seiten eines Elements relativ zu mehreren Ankern positionieren können, indem Sie verschiedene<anchor-name>-Werte innerhalb unterschiedlicheranchor()-Funktionen auf demselben Element angeben, ist das positionierte Element nur mit einem einzigen Anker assoziiert. <anchor-side>-
Gibt die Position relativ zu einer Seite oder Seiten des Ankers an. Gültige Werte umfassen das
centerdes Ankers, physische (top,left, usw.) oder logische (start,self-end, usw.) Seiten des Ankers oder einen<percentage>zwischen dem Start (0%) und dem Ende (100%) der Achse der Inset-Eigenschaft, auf deranchor()gesetzt ist. Wenn ein Wert verwendet wird, der nicht kompatibel mit der Inset-Eigenschaft ist, auf der dieanchor()-Funktion gesetzt ist, wird der Rückfallwert verwendet. <fallback>-
Ein
<length-percentage>, der den Abstand angibt, der als Rückfallwert verwendet werden soll, wenn das Element nicht absolut oder fix positioniert ist, wenn der verwendete<anchor-side>-Wert nicht kompatibel mit der Inset-Eigenschaft ist, auf der dieanchor()-Funktion gesetzt ist, oder wenn das Ankerelement nicht existiert.
Der Rückgabewert der anchor()-Funktion ist ein Längenwert, der basierend auf der Position des Ankers berechnet wird. Wenn Sie eine Länge oder einen Prozentsatz direkt auf der Inset-Eigenschaft eines ankerpositionierten Elements setzen, wird es so positioniert, als ob es nicht an das Ankerelement gebunden wäre. Dies ist das gleiche Verhalten, das auftritt, wenn der <anchor-side>-Wert mit der Inset-Eigenschaft, auf der es gesetzt ist, unvereinbar ist und der Rückfall verwendet wird. Diese beiden Deklarationen sind äquivalent:
bottom: anchor(right, 50px);
bottom: 50px;
Beide platzieren das positionierte Element 50px über dem unteren Rand des nächstgelegenen positionierten Vorfahren des Elements (falls vorhanden) oder des initialen enthaltenden Blocks.
Die am häufigsten verwendeten anchor()-Parameter beziehen sich auf eine Seite des Standardankers. Sie werden auch häufig entweder eine margin hinzufügen, um Abstand zwischen dem Rand des Ankers und dem positionierten Element zu schaffen, oder anchor() innerhalb einer calc()-Funktion verwenden, um diesen Abstand hinzuzufügen.
Beispielsweise positioniert diese Regel den linken Rand des positionierten Elements bündig mit dem rechten Rand des Ankerelements und fügt dann etwas margin-left hinzu, um etwas Abstand zwischen den Rändern zu schaffen:
.positionedElement {
left: anchor(right);
margin-left: 10px;
}
Der Rückgabewert einer anchor()-Funktion ist eine Länge. Dies bedeutet, dass Sie es innerhalb einer calc()-Funktion verwenden können. Diese Regel positioniert den logischen Block-Endrand des positionierten Elements 10px vom logischen Block-Startrand des Ankerelements entfernt, wobei der Abstand innerhalb der calc()-Funktion hinzugefügt wird, sodass wir keinen Rand hinzufügen müssen:
.positionedElement {
inset-block-end: calc(anchor(start) + 10px);
}
anchor() Beispiel
Werfen wir einen Blick auf ein anchor()-Beispiel in Aktion. Wir haben dasselbe HTML wie in den vorherigen Beispielen verwendet, aber mit einigen Fülltexten, die darunter und darüber platziert sind, um den Inhalt seines Containers überlaufen zu lassen und zu scrollen. Wir geben dem Ankerelement denselben Ankernamen wie in den vorherigen Beispielen:
.anchor {
anchor-name: --my-anchor;
}
Die Infobox ist über den Ankernamen mit dem Anker assoziiert und wurde mit fixierter Positionierung versehen. Indem wir die inset-block-start- und inset-inline-start-Eigenschaften einschließen (die äquivalent zu top und left in horizontalen Links-nach-Rechts Schreibrichtungen sind), haben wir sie an den Anker gebunden. Wir fügen der Infobox einen margin hinzu, um Platz zwischen dem positionierten Element und seinem Anker zu schaffen:
.infobox {
position-anchor: --my-anchor;
position: fixed;
inset-block-start: anchor(end);
inset-inline-start: anchor(self-end);
margin: 5px 0 0 5px;
}
Lassen Sie uns die Inset-Eigenschafts-Positionierungsdeklarationen genauer betrachten:
inset-block-start: anchor(end): Dies setzt den Blockstart-Rand des positionierten Elements auf den Blockend-Rand des Ankers und berechnet ihn mit deranchor(end)-Funktion.inset-inline-start: anchor(self-end): Dies setzt den Blockstart-Rand des positionierten Elements auf den Blockend-Rand des Ankers und berechnet ihn mit deranchor(self-end)-Funktion.
Dies ergibt folgendes Ergebnis:
Das positionierte Element befindet sich 5px unterhalb und 5px rechts vom Ankerelement. Wenn Sie das Dokument nach oben und unten scrollen, behält das positionierte Element seine Position relativ zum Ankerelement bei — es ist an das Ankerelement und nicht an den Viewport fixiert.
Festlegung eines position-area
Die position-area-Eigenschaft bietet eine Alternative zur anchor()-Funktion für die Positionierung von Elementen relativ zu Ankern. Die position-area-Eigenschaft arbeitet mit dem Konzept eines 3x3-Gitters von Kacheln, wobei das Ankerelement die mittlere Kachel ist. Die position-area-Eigenschaft kann verwendet werden, um das ankerpositionierte Element in einer der neun Kacheln zu positionieren oder es über zwei oder drei Kacheln zu erstrecken.
Die Rasterkacheln werden in Reihen und Spalten unterteilt:
- Die drei Reihen werden durch die physikalischen Werte
top,centerundbottomdargestellt. Sie haben auch logische Äquivalente wiestart,centerundendsowie Koordinatenäquivalente wiey-start,centerundy-end. - Die drei Spalten werden durch die physikalischen Werte
left,centerundrightdargestellt. Sie haben auch logische Äquivalente wiestart,centerundendsowie Koordinatenäquivalente wiex-start,centerundx-end.
Die Dimensionen der mittleren Kachel werden vom enthaltenden Block des Ankerelements definiert, während der Abstand zwischen der mittleren Kachel und dem äußeren Rand des Rasters vom enthaltenden Block des positionierten Elements definiert wird.
position-area-Eigenschaftswerte bestehen aus einem oder zwei Werten, basierend auf den oben beschriebenen Reihen- und Spaltenwerten, mit Optionen zum Erstrecken, um den Bereich des Rasters zu definieren, in dem das Element positioniert werden soll.
Zum Beispiel:
Sie können zwei Werte angeben, um das positionierte Element in einer bestimmten Gitterschnelle zu platzieren. Zum Beispiel:
top left(logisches Äquivalentstart start) platziert das positionierte Element in der oberen linken Kachel.bottom center(logisches Äquivalentend center) platziert das positionierte Element in der unteren mittleren Kachel.
Sie können einen Reihen- oder Spaltenwert plus einen span-*-Wert angeben. Der erste Wert gibt die Reihe oder Spalte an, in der das positionierte Element platziert werden soll, und die andere gibt die Menge dieser Spalte an, die es erstrecken soll. Zum Beispiel:
top span-leftbewirkt, dass das positionierte Element in der obersten Reihe platziert wird und sich über die mittlere und linke Kachel dieser Reihe erstreckt.y-end span-x-endbewirkt, dass das positionierte Element am Ende der y-Spalte platziert wird und sich über die mittlere und x-end-Kachel dieser Spalte erstreckt.block-end span-allbewirkt, dass das positionierte Element in der block-end-Reihe platziert wird und sich über die inline-start-, center- und inline-end-Kacheln dieser Reihe erstreckt.
Wenn Sie nur einen Wert angeben, ist die Wirkung je nach gesetztem Wert unterschiedlich:
- Ein physischer Seitenwert (
top,bottom,leftoderright) oder Koordinatenwert (y-start,y-end,x-start,x-end) wirkt, als ob der andere Wertspan-allist. Zum Beispiel ergibttopden gleichen Effekt wietop span-all. - Ein logischer Seitenwert (
startoderend) wirkt, als ob der andere Wert auf den gleichen Wert gesetzt ist; zum Beispiel ergibtstartden gleichen Effekt wiestart start. - Ein Wert von
centerwirkt, als ob beide Werte aufcentergesetzt sind (d.h.center center).
Hinweis:
Siehe die <position-area>-Wert-Referenzseite für eine detaillierte Beschreibung aller verfügbaren Werte. Das Mischen eines logischen Wertes mit einem physischen Wert macht die Deklaration ungültig.
Lassen Sie uns einige dieser Werte demonstrieren; dieses Beispiel verwendet dasselbe HTML und dieselben grundlegenden CSS-Stile wie das vorherige Beispiel, mit Ausnahme, dass wir ein <select>-Element eingeschlossen haben, um das Ändern des position-area-Werts des positionierten Elements zu ermöglichen.
Die Infobox wird mit fixierter Positionierung versehen und mit dem Anker über CSS assoziiert. Bei dem Ladevorgang ist sie so eingestellt, dass sie mit position-area: top; an den Anker gebunden ist, was dazu führt, dass sie oben im position-area-Gitter positioniert wird. Dies wird überschrieben, sobald Sie andere Werte aus dem <select>-Menü auswählen.
.infobox {
position: fixed;
position-anchor: --my-anchor;
position-area: top;
}
Wir fügen auch ein kurzes Skript ein, um neue position-area-Werte aus dem <select>-Menü auf die Infobox anzuwenden:
const infobox = document.querySelector(".infobox");
const selectElem = document.querySelector("select");
selectElem.addEventListener("change", () => {
const area = selectElem.value;
// Set the position-area to the value chosen in the select box
infobox.style.positionArea = area;
});
Versuchen Sie, neue position-area-Werte aus dem <select>-Menü auszuwählen, um zu sehen, welchen Effekt sie auf die Position der Infobox haben:
Breite des positionierten Elements
Im obigen Beispiel haben wir das positionierte Element in keiner Dimension explizit dimensioniert. Wir haben bewusst auf Größenangaben verzichtet, um Ihnen das Verhalten zu zeigen, das dies verursacht.
Wenn ein positioniertes Element ohne explizite Größe in position-area-Gitterzellen platziert wird, richtet es sich mit dem angegebenen Rasterbereich aus und verhält sich so, als ob width auf max-content gesetzt wäre. Es wird entsprechend seinem enthaltenden Block-Größe dimensioniert, die die Breite seines Inhalts ist. Diese Größe wurde durch das Setzen von position: fixed auferlegt. Automatisch dimensionierte absolut und fix positionierte Elemente werden automatisch dimensioniert und dehnen sich so weit aus, wie es nötig ist, um den Textinhalt zu passen, während sie durch den Rand des Viewports begrenzt werden. In diesem Fall, wenn es auf der linken Seite des Gitters mit jedem left- oder inline-start-Wert platziert wird, wird der Text umgebrochen. Wenn die max-content-Größe des angedockten Elements schmaler oder kürzer als ihr Anker ist, werden sie nicht wachsen, um die Größe des Ankers zu erreichen.
Wenn das positionierte Element vertikal zentriert ist, beispielsweise mit position-area: bottom center, wird es mit der angegebenen Gitterzelle ausgerichtet und die Breite wird gleich der des Ankerelements sein. In diesem Fall ist seine minimale Höhe die Größe des enthaltenden Blocks des Ankerelements. Es wird nicht überlaufen, da das min-width auf min-content gesetzt ist, was bedeutet, dass es mindestens so breit wie sein längstes Wort ist.
Zentrierung auf dem Anker mit anchor-center
Während Sie das ankerpositionierte Element mit den center-Werten von position-area zentrieren können, bieten Inset-Eigenschaften in Kombination mit der anchor()-Funktion mehr Kontrolle über die genaue Position. Die CSS-Ankerpositionierung bietet eine Möglichkeit, ein ankerpositioniertes Element relativ zu seinem Anker zu zentrieren, wenn Inset-Eigenschaften statt position-area verwendet werden, um es zu binden.
Die Eigenschaften justify-self, align-self, justify-items und align-items (und ihre place-items und place-self Shorthands) existieren, um Entwicklern zu ermöglichen, Elemente einfach in der Inline- oder Block-Richtung innerhalb verschiedener Layout-Systeme zu auszurichten, beispielsweise entlang der Haupt- oder Querachse im Falle von Flex-Kindern. Die CSS-Ankerpositionierung bietet einen zusätzlichen Wert für diese Eigenschaften, anchor-center, der ein positioniertes Element mit dem Zentrum seines Standardankers ausrichtet.
Dieses Beispiel verwendet dasselbe HTML und dieselben grundlegenden CSS-Stile wie das vorherige Beispiel. Die Infobox hat eine feste Positionierung und ist an der unteren Kante des Ankers verankert. justify-self: anchor-center wird dann verwendet, um sicherzustellen, dass es horizontal auf dem Zentrum des Ankers zentriert ist:
.infobox {
position: fixed;
position-anchor: --my-anchor;
top: calc(anchor(bottom) + 5px);
justify-self: anchor-center;
}
Dies zentriert das ankerpositionierte Element am unteren Rand des Ankers:
Dimensionierung von Elementen basierend auf der Ankergröße
Neben der Positionierung eines Elements relativ zur Position seines Ankers, können Sie auch ein Element relativ zur Größe seines Ankers dimensionieren, indem Sie die anchor-size()-Funktion innerhalb eines Dimensionierungseigenschaftswerts verwenden.
Die Eigenschaften, die einen anchor-size()-Wert annehmen können, sind unter anderem:
widthheightmin-widthmin-heightmax-widthmax-heightblock-sizeinline-sizemin-block-sizemin-inline-sizemax-block-sizemax-inline-size
anchor-size()-Funktionen werden zu <length>-Werten aufgelöst. Ihre Syntax sieht folgendermaßen aus:
anchor-size(<anchor-name> <anchor-size>, <length-percentage>)
<anchor-name>-
Der
<dashed-ident>-Name wird als Wert deranchor-name-Eigenschaft des Ankerelements gesetzt, relativ zum dem Sie die Dimensionierung des Elements möchten. Wenn ausgelassen, wird der Standardanker des Elements verwendet, welches der Anker ist, der in derposition-anchor-Eigenschaft referenziert wird. <anchor-size>-
Gibt die Dimension des Ankerelements an, relativ zu der das positionierte Element dimensioniert wird. Dies kann durch physikalische (
widthoderheight) oder logische (inline,block,self-inlineoderself-block) Werte ausgedrückt werden. <length-percentage>-
Gibt die Größe an, die als Rückfallwert verwendet werden soll, wenn das Element nicht absolut oder fix positioniert ist oder wenn das Ankerelement nicht existiert.
Die häufigsten anchor-size()-Funktionen, die Sie verwenden werden, beziehen sich einfach auf eine Dimension des Standardankers. Sie können sie auch innerhalb von calc()-Funktionen verwenden, um die angewandte Größe auf das positionierte Element zu ändern.
Beispielsweise dimensioniert diese Regel die Breite des positionierten Elements gleich der Breite des Standardankerelements:
.elem {
width: anchor-size(width);
}
Diese Regel dimensioniert die Inline-Größe des positionierten Elements auf das Vierfache der Inline-Größe des Ankerelements. Die Multiplikation erfolgt innerhalb einer calc()-Funktion:
.elem {
inline-size: calc(anchor-size(self-inline) * 4);
}
Lassen Sie uns einen Blick auf ein Beispiel werfen. Das HTML und die grundlegenden CSS sind die gleichen wie in den vorherigen Beispielen, mit der Ausnahme, dass das Ankerelement ein tabindex="0"-Attribut hat, um es fokussierbar zu machen. Die Infobox hat eine feste Positionierung und ist auf die gleiche Weise wie zuvor mit dem Anker verbunden. Diesmal verankern wir es jedoch auf der rechten Seite des Ankers mit einer position-area und geben ihm eine Breite, die fünfmal die Breite des Ankers beträgt:
.infobox {
position: fixed;
position-anchor: --my-anchor;
position-area: right;
margin-left: 5px;
width: calc(anchor-size(width) * 5);
}
Zusätzlich erhöhen wir die width-Eigenschaft des Ankerelements bei :hover und :focus und geben ihm eine transition, sodass sie bei einem Zustandswechsel animiert wird.
.anchor {
text-align: center;
width: 30px;
transition: 1s width;
}
.anchor:hover,
.anchor:focus {
width: 50px;
}
Fahren Sie mit der Maus über oder fokussieren Sie auf das Ankerelement mit der Tabulatortaste – das positionierte Element wächst, während der Anker wächst und demonstriert, dass die Größe des ankerpositionierten Elements relativ zu seinem Anker ist:
Weitere Verwendungen von anchor-size()
Sie können anchor-size() auch in physischen und logischen Inset- und Margin-Eigenschaften verwenden. Die folgenden Abschnitten erläutern diese Verwendungen detaillierter, bevor ein Anwendungsbeispiel angeboten wird.
Setzen der Elementposition basierend auf der Ankergröße
Sie können die anchor-size()-Funktion innerhalb eines Inset-Eigenschaft-Wertes verwenden, um Elemente basierend auf der Größe ihres Ankerelements zu positionieren, zum Beispiel:
left: anchor-size(width);
inset-inline-end: anchor-size(--my-anchor height, 100px);
Dies positioniert ein Element nicht relativ zur Position seines Ankers wie die anchor()-Funktion oder die position-area-Eigenschaft (siehe Positionieren von Elementen relativ zu ihrem Anker, oben); das Element wird seine Position nicht ändern, wenn sich sein Anker ändert. Stattdessen wird das Element gemäß den normalen Regeln des absolute oder fixed positioniert.
Dies kann in einigen Situationen nützlich sein. Zum Beispiel, wenn Ihr Ankerelement sich nur vertikal bewegen kann und immer neben dem Rand seines nächstgelegenen positionierten Vorfahren horizontal bleibt, können Sie left: anchor-size(width) verwenden, um das ankerpositionierte Element immer rechts neben seinem Anker zu positionieren, selbst wenn sich die Ankerbreite ändert.
Setzen der Elementmarge basierend auf der Ankergröße
Sie können die anchor-size()-Funktion innerhalb einer margin-*-Eigenschaft verwenden, um Elementabstände basierend auf der Größe ihres Ankerelements zu setzen, zum Beispiel:
margin-left: calc(anchor-size(width) / 4);
margin-block-start: anchor-size(--my-anchor self-block, 20px);
Dies kann in Fällen nützlich sein, in denen Sie die Marge eines ankerpositionierten Elements immer auf denselben Prozentsatz der Breite des Ankerelements setzen möchten, selbst wenn sich die Breite ändert.
anchor-size()-Position und Margin-Beispiel
Lassen Sie uns ein Beispiel betrachten, in dem wir die Marge und Position eines ankerpositionierten Elements relativ zur Breite des Ankerelements setzen.
Im HTML spezifizieren wir zwei <div>-Elemente, ein anchor-Element und ein infobox-Element, das wir relativ zum Anker positionieren werden. Wir geben dem Ankerelement ein tabindex-Attribut, sodass es über die Tastatur fokussiert werden kann. Wir fügen auch Fülltext hinzu, um den <body> hoch genug zu machen, um Scrollen zu erfordern, aber dies wurde aus Gründen der Kürze versteckt.
<div class="anchor" tabindex="0">⚓︎</div>
<div class="infobox">
<p>Infobox.</p>
</div>
Im CSS deklarieren wir zuerst das anchor-<div> als Ankerelement, indem wir ihm einen anchor-name zuweisen. Das positionierte Element hat seine position-Eigenschaft auf absolute gesetzt und ist über seine position-anchor-Eigenschaft mit dem Ankerelement assoziiert. Wir setzen auch absolute height- und width-Dimensionen auf den Anker und die Infobox sowie eine transition auf den Anker, sodass Dimensionierungsänderungen bei einem Zustandswechsel glatt animiert werden:
.anchor {
anchor-name: --my-anchor;
width: 100px;
height: 100px;
transition: 1s all;
}
.infobox {
position-anchor: --my-anchor;
position: absolute;
height: 100px;
width: 100px;
}
Jetzt kommen wir zum interessantesten Teil. Hier setzen wir das Anker-width auf 300px, wenn es gehoben oder fokussiert wird. Wir setzen dann den:
top-Wert der Infobox aufanchor(top). Dies bewirkt, dass der obere Rand der Infobox immer mit dem oberen Rand des Ankers eine Linie bildet.left-Wert der Infobox aufanchor-size(width). Dies bewirkt, dass der linke Rand der Infobox in dem angegebenen Abstand vom linken Rand des nächstgelegenen positionierten Vorfahren positioniert wird. In diesem Fall ist der angegebene Abstand gleich der Breite des Ankerelements und der nächstgelegene positionierte Vorfahre ist das<body>-Element, sodass die Infobox rechts neben dem Anker erscheint.margin-left-Wert, umcalc(anchor-size(width)/4). Dies bewirkt, dass die Infobox immer einen linken Abstand hat, der sie vom Anker trennt und gleich einem Viertel der Breite des Ankers ist.
.anchor:hover,
.anchor:focus {
width: 300px;
}
.infobox {
top: anchor(top);
left: anchor-size(width);
margin-left: calc(anchor-size(width) / 4);
}
Das gerenderte Ergebnis sieht wie folgt aus:
Versuchen Sie, zum Anker zu wechseln oder mit dem Mauszeiger darüber zu schweben, und beachten Sie, wie sich die Position und der linke Abstand der Infoboxin in Proportion zur Breite des Ankerelements vergrößert.