Elemente über CSS-Ankerpositionierung miteinander verbinden

Wie nutzen Sie derzeit das Tethering zwischen einem Element? Sie können versuchen, ihre Positionen zu verfolgen, oder ein Wrapper-Element verwenden.

<!-- index.html -->
<div class="container">
  <a href="/link" class="anchor">I’m the anchor</a>
  <div class="anchored">I’m the anchored thing</div>
</div>
/* styles.css */
.container {
  position: relative;
}
.anchored {
  position: absolute;
}

Diese Lösungen sind oft nicht ideal. Sie benötigen JavaScript oder die Einführung von zusätzlichem Markup. Die CSS Anchor Positioning API möchte dieses Problem lösen, indem sie eine CSS API für Tethering-Elemente bereitstellt. Sie bietet die Möglichkeit, ein Element basierend auf Position und Größe anderer Elemente zu positionieren und zu vergrößern.

Die Abbildung zeigt ein Mockup-Browserfenster, in dem der Aufbau einer Kurzinfo detailliert dargestellt ist.

Unterstützte Browser

Sie können die CSS Anchor Positioning API in Chrome Canary hinter dem Flag „Experimental Web Platform Features“ ausprobieren. Öffnen Sie zum Aktivieren dieses Flags Chrome Canary und rufen Sie chrome://flags auf. Aktivieren Sie dann das Flag „Experimental web platform features“.

Außerdem wird vom Oddbird-Team ein Polyfill in Entwicklung sein. Prüfen Sie das Repository unter github.com/oddbird/css-anchor-positioning.

So können Sie prüfen, ob die Verankerung unterstützt wird:

@supports(anchor-name: --foo) {
  /* Styles... */
}

Diese API befindet sich noch in der Testphase und kann sich noch ändern. In diesem Artikel erhalten Sie einen Überblick über die wichtigsten Teile. Die aktuelle Implementierung ist außerdem nicht vollständig mit den Spezifikationen der Preisvergleichsportal-Arbeitsgruppe synchron.

Das Problem

Wozu dient das? Ein auffälliger Anwendungsfall wäre das Erstellen von Kurzinfos oder einer Websitevariante, die an Kurzinfos erinnert. In diesem Fall ist es oft sinnvoll, die Kurzinfo per Tethering mit dem Inhalt zu verknüpfen, auf den sie verweist. Es besteht häufig ein Bedarf an einer Möglichkeit, ein Element an ein anderes Tethering zu binden. Außerdem erwarten Sie, dass das Tethering durch die Interaktion mit der Seite nicht unterbrochen wird, z. B. wenn ein Nutzer scrollt oder die Größe der Benutzeroberfläche ändert.

Ein weiteres Problem besteht darin, dass Sie dafür sorgen möchten, dass das per Tethering gebundene Element sichtbar bleibt, z. B. wenn Sie eine Kurzinfo öffnen und diese durch die Darstellungsbereichgrenzen abgeschnitten wird. Dies ist für die Nutzenden möglicherweise nicht besonders attraktiv. Die Kurzinfo soll angepasst werden.

Aktuelle Lösungen

Derzeit gibt es verschiedene Möglichkeiten, das Problem anzugehen.

Der erste ist der rudimentäre Ansatz „Wrap the anchor“. Sie nehmen beide Elemente und verpacken sie in einem Container. Anschließend können Sie position verwenden, um die Kurzinfo relativ zum Anker zu positionieren.

<div class="containing-block">
  <div class="tooltip">Anchor me!</div>
  <a class="anchor">The anchor</a>
</div>
.containing-block {
  position: relative;
}

.tooltip {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
}

Sie können den Container verschieben und alles bleibt dort größtenteils, wo Sie es haben möchten.

Ein anderer Ansatz könnte sein, wenn Sie die Position des Ankers kennen oder ihn irgendwie nachverfolgen können. Sie können ihn mithilfe von benutzerdefinierten Eigenschaften an Ihre Kurzinfo übergeben.

<div class="tooltip">Anchor me!</div>
<a class="anchor">The anchor</a>
:root {
  --anchor-width: 120px;
  --anchor-top: 40vh;
  --anchor-left: 20vmin;
}

.anchor {
  position: absolute;
  top: var(--anchor-top);
  left: var(--anchor-left);
  width: var(--anchor-width);
}

.tooltip {
  position: absolute;
  top: calc(var(--anchor-top));
  left: calc((var(--anchor-width) * 0.5) + var(--anchor-left));
  transform: translate(-50%, calc(-100% - 10px));
}

Aber was ist, wenn Sie die Position des Ankers nicht kennen? Wahrscheinlich müssen Sie in JavaScript eingreifen. Sie könnten in etwa wie im folgenden Code vorgehen, was aber bedeutet, dass Ihre Stile nun aus dem CSS-Code in JavaScript übertragen werden.

const setAnchorPosition = (anchored, anchor) => {
  const bounds = anchor.getBoundingClientRect().toJSON();
  for (const [key, value] of Object.entries(bounds)) {
    anchored.style.setProperty(`--${key}`, value);
  }
};

const update = () => {
  setAnchorPosition(
    document.querySelector('.tooltip'),
    document.querySelector('.anchor')
  );
};

window.addEventListener('resize', update);
document.addEventListener('DOMContentLoaded', update);

Das wirft nun einige Fragen auf:

  • Wann berechne ich die Stile?
  • Wie berechne ich die Stile?
  • Wie oft berechne ich die Stile?

Wird das Problem dadurch gelöst? Vielleicht funktioniert es für Ihren Anwendungsfall, aber es gibt ein Problem: Unsere Lösung passt sich nicht an. Sie reagiert nicht. Was passiert, wenn mein verankertes Element vom Darstellungsbereich abgeschnitten wird?

Jetzt müssen Sie entscheiden, ob Sie darauf reagieren möchten und wie. Die Zahl der Fragen und Entscheidungen, die Sie treffen müssen, nimmt stetig zu. Sie müssen lediglich ein Element an einem anderen verankern. Im Idealfall passt sich Ihre Lösung an die Umgebung an und reagiert darauf.

Um diese Probleme zu lindern, könnten Sie nach einer JavaScript-Lösung greifen. Das verursacht Kosten für das Hinzufügen einer Abhängigkeit zu Ihrem Projekt und kann je nach Verwendung zu Leistungsproblemen führen. Beispielsweise verwenden einige Pakete requestAnimationFrame, damit die Position korrekt bleibt. Dies bedeutet, dass Sie und Ihr Team sich mit dem Paket und seinen Konfigurationsoptionen vertraut machen müssen. Dadurch werden Ihre Fragen und Entscheidungen möglicherweise nicht reduziert, sondern stattdessen geändert. Dies ist Teil des „Warum“ für die CSS-Ankerpositionierung. So vermeiden Sie, bei der Berechnung der Position Leistungsprobleme zu berücksichtigen.

So könnte der Code bei Verwendung des Pakets floating-ui, einem bei diesem Problem häufig verwendeten Paket, aussehen:

import {computePosition, flip, offset, autoUpdate} from 'https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.2.1/+esm';

const anchor = document.querySelector('.anchor')
const tooltip = document.querySelector('.tooltip')

const updatePosition = () => {  
  computePosition(anchor, tooltip, {
    placement: 'top',
    middleware: [offset(10), flip()]
  })
    .then(({x, y}) => {
      Object.assign(tooltip.style, {
        left: `${x}px`,
        top: `${y}px`
      })
  })
};

const clean = autoUpdate(anchor, tooltip, updatePosition);

Versuchen Sie, den Anker in dieser Demo, in der dieser Code verwendet wird, neu zu positionieren.

Die „Kurzinfo“ verhält sich möglicherweise nicht wie erwartet. Sie reagiert darauf, wenn sie sich auf der Y-Achse außerhalb des Darstellungsbereichs befindet, aber nicht auf der X-Achse. In der Dokumentation finden Sie wahrscheinlich eine Lösung, die für Sie funktioniert.

Aber es kann viel Zeit in Anspruch nehmen, ein Paket zu finden, das für Ihr Projekt geeignet ist. Das sind zusätzliche Entscheidungen und kann frustrierend sein, wenn es nicht so funktioniert, wie Sie es möchten.

Ankerpositionierung verwenden

Geben Sie die CSS-Anchor Positioning API ein. Der Gedanke ist, die Stile im CSS-Code beizubehalten und die Anzahl der Entscheidungen, die Sie treffen müssen, zu reduzieren. Sie hoffen, das gleiche Ergebnis zu erzielen, aber das Ziel ist es, die Nutzung für Entwickler zu verbessern.

  • JavaScript ist nicht erforderlich.
  • Lassen Sie den Browser anhand Ihrer Anleitung die beste Position ermitteln.
  • Keine Abhängigkeiten von Drittanbietern mehr
  • Keine Wrapper-Elemente.
  • Funktioniert mit Elementen auf der obersten Ebene.

Lassen Sie uns das Problem, das wir oben zu lösen versuchten, reproduzieren und angehen. Betrachten Sie stattdessen die Analogie eines Bootes mit einem Anker. Diese stellen das verankerte Element und den Anker dar. Das Wasser stellt den übergeordneten Block dar.

Zuerst müssen Sie auswählen, wie der Anker definiert werden soll. Dazu können Sie in Ihrem CSS-Code die Eigenschaft anchor-name für das Ankerelement festlegen. Ein dashed-ident-Wert ist zulässig.

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

Alternativ können Sie mit dem Attribut anchor einen Anker in Ihrem HTML-Code definieren. Der Attributwert ist die ID des Ankerelements. Dadurch wird ein impliziter Anker erstellt.

<a id="my-anchor" class="anchor"></a>
<div anchor="my-anchor" class="boat">I’m a boat!</div>

Nachdem Sie einen Anker definiert haben, können Sie die Funktion anchor verwenden. Die Funktion anchor verwendet drei Argumente:

  • Ankerelement: Der anchor-name des zu verwendenden Ankers. Wenn Sie einen implicit-Anker verwenden möchten, können Sie den Wert auch weglassen. Er kann über die HTML-Beziehung oder mit einer anchor-default-Eigenschaft mit einem anchor-name-Wert definiert werden.
  • Ankerseite:Keyword der Position, die Sie verwenden möchten. Das könnte top, right, bottom, left, center usw. sein. Sie können auch einen Prozentsatz übergeben. Beispielsweise würden 50% center entsprechen.
  • Fallback: Dies ist ein optionaler Fallback-Wert, bei dem eine Länge oder ein Prozentsatz angegeben werden kann.

Sie verwenden die Funktion anchor als Wert für die Einfügungsattribute (top, right, bottom, left oder ihre logischen Entsprechungen) des verankerten Elements. Sie können auch die anchor-Funktion in calc verwenden:

.boat {
  bottom: anchor(--my-anchor top);
  left: calc(anchor(--my-anchor center) - (var(--boat-size) * 0.5));
}

 /* alternative with anchor-default */
.boat {
  anchor-default: --my-anchor;
  bottom: anchor(top);
  left: calc(anchor(center) - (var(--boat-size) * 0.5));
}

Es gibt keine center-Einfügungseigenschaft. Daher kann calc verwendet werden, wenn Sie die Größe des verankerten Elements kennen. Warum nicht translate? Sie könnten Folgendes verwenden:

.boat {
  anchor-default: --my-anchor;
  bottom: anchor(top);
  left: anchor(center);
  translate: -50% 0;
}

Der Browser berücksichtigt transformierte Positionen für verankerte Elemente jedoch nicht. Es wird deutlich, warum dies bei der Berücksichtigung von Positions-Fallbacks und der automatischen Positionierung wichtig ist.

Vielleicht ist Ihnen schon aufgefallen, dass oben die benutzerdefinierte Eigenschaft --boat-size verwendet wurde. Wenn Sie jedoch die Größe des verankerten Elements basierend auf der Größe des Ankers festlegen möchten, können Sie auch auf diese Größe zugreifen. Anstatt sie selbst zu berechnen, können Sie die Funktion anchor-size verwenden. So nehmen Sie zum Beispiel an, dass unser Boot viermal so breit ist wie der Anker:

.boat {
  width: calc(4 * anchor-size(--my-anchor width));
}

Mit anchor-size(--my-anchor height) können Sie auch auf die Höhe zugreifen. Außerdem können Sie die Größe der Achsen oder der beiden Achsen einstellen.

Wie gehen Sie vor, wenn Sie ein Element mit absolute-Positionierung verankern möchten? Als Regel gilt, dass die Elemente nicht gleichgeordnet sein können. In diesem Fall können Sie den Anker in einen Container mit der Position relative umschließen. Daran können Sie dann verankern.

<div class="anchor-wrapper">
  <a id="my-anchor" class="anchor"></a>
</div>
<div class="boat">I’m a boat!</div>

In dieser Demo kannst du den Anker einfach verschieben und das Boot folgt dir.

Scrollposition wird erfasst

In einigen Fällen kann sich das Ankerelement in einem scrollbaren Container befinden. Gleichzeitig kann sich das verankerte Element außerhalb dieses Containers befinden. Da das Scrollen in einem anderen Thread als dem Layout erfolgt, müssen Sie eine Möglichkeit haben, ihn zu verfolgen. Mit der Eigenschaft anchor-scroll ist das möglich. Sie legen ihn für das verankerte Element fest und weisen ihm den Wert des zu erfassenden Ankers zu.

.boat { anchor-scroll: --my-anchor; }

In dieser Demo kannst du anchor-scroll über das Kästchen in der Ecke ein- und ausschalten.

Die Analogie liegt hier jedoch ein wenig flach, denn in einer idealen Welt befinden sich sowohl Ihr Boot als auch Ihr Anker im Wasser. Außerdem fördern Funktionen wie die Popover API die Möglichkeit, ähnliche Elemente in der Nähe zu halten. Die Ankerpositionierung funktioniert jedoch nur bei Elementen, die sich in der obersten Ebene befinden. Dies ist einer der Hauptvorteile der API: Die Möglichkeit, Elemente in verschiedenen Abläufen per Tethering zu verknüpfen.

Sehen Sie sich diese Demo an, die einen scrollbaren Container mit Ankern und Kurzinfos enthält. Die Kurzinfo-Elemente, bei denen es sich um Pop-over-Elemente handelt, befinden sich möglicherweise nicht am selben Standort wie die Anker:

Sie werden jedoch feststellen, wie die Pop-over ihre jeweiligen Ankerlinks erfassen. Sie können die Größe des scrollbaren Containers ändern und die Positionen werden automatisch aktualisiert.

Positions-Fallback und automatische Positionierung

An dieser Stelle steigt die Leistung der Ankerposition eine Ebene nach oben. Ein position-fallback kann das verankerte Element basierend auf einer Reihe von Fallbacks positionieren, die Sie angeben. Sie steuern den Browser mit Ihren Stilen und lassen ihn die Position für Sie berechnen.

Der häufigste Anwendungsfall hier ist eine Kurzinfo, die zwischen der Anzeige über oder unter einem Anker wechseln sollte. Dieses Verhalten hängt davon ab, ob die Kurzinfo durch den Container abgeschnitten wird. Dieser Container ist normalerweise der Darstellungsbereich.

Wenn Sie sich den Code der letzten Demo genauer ansehen, sehen Sie, dass eine position-fallback-Property verwendet wird. Beim Scrollen im Container haben Sie möglicherweise bemerkt, dass diese verankerten Pop-overs springen. Dies geschah, als sich die jeweiligen Anker der Grenze des Darstellungsbereichs nähern. Momentan versuchen die Pop-over, im Darstellungsbereich zu bleiben.

Bevor eine explizite position-fallback erstellt wird, bietet die Ankerpositionierung auch eine automatische Positionierung. Sie erhalten dieses Umdrehen kostenlos, wenn Sie den Wert auto sowohl in der Ankerfunktion als auch in der entgegengesetzten Inset-Eigenschaft verwenden. Wenn Sie beispielsweise anchor für bottom verwenden, legen Sie top auf auto fest.

.tooltip {
  position: absolute;
  bottom: anchor(--my-anchor auto);
  top: auto;
}

Die Alternative zur automatischen Positionierung ist die Verwendung eines expliziten position-fallback. Dazu müssen Sie eine Positions-Fallback-Gruppe definieren. Der Browser durchläuft diese Schritte, bis er eine Adresse findet, die er verwenden kann, und wendet dann diese Positionierung an. Wenn kein passendes Ergebnis gefunden wird, wird standardmäßig die erste definierte verwendet.

Ein position-fallback, der versucht, die Kurzinfos oben und unten anzuzeigen, könnte so aussehen:

@position-fallback --top-to-bottom {
  @try {
    bottom: anchor(top);
    left: anchor(center);
  }

  @try {
    top: anchor(bottom);
    left: anchor(center);
  }
}

Wenn Sie dies auf die Kurzinfos anwenden, sieht das so aus:

.tooltip {
  anchor-default: --my-anchor;
  position-fallback: --top-to-bottom;
}

Wenn du anchor-default verwendest, kannst du position-fallback auch für andere Elemente verwenden. Sie können auch eine benutzerdefinierte Eigenschaft mit Umfang verwenden, um anchor-default festzulegen.

Betrachten Sie diese Demo noch einmal mit dem Boot. Es ist ein position-fallback-Set vorhanden. Wenn du die Position des Ankers änderst, bewegt sich das Boot so, dass es im Container bleibt. Versuchen Sie, auch den Abstandswert zu ändern, um die Abstände des Texts anzupassen. Beachten Sie, wie der Browser die Positionierung korrigiert. Die Positionen werden geändert, indem die Rasterausrichtung des Containers geändert wird.

position-fallback ist diesmal ausführlicher und testet Positionen im Uhrzeigersinn.

.boat {
  anchor-default: --my-anchor;
  position-fallback: --compass;
}

@position-fallback --compass {
  @try {
    bottom: anchor(top);
    right: anchor(left);
  }

  @try {
    bottom: anchor(top);
    left: anchor(right);
  }

  @try {
    top: anchor(bottom);
    right: anchor(left);
  }

  @try {
    top: anchor(bottom);
    left: anchor(right);
  }
}


Beispiele

Nachdem Sie nun eine Vorstellung von den wichtigsten Funktionen für die Ankerposition haben, schauen wir uns neben den Kurzinfos einige interessante Beispiele an. Diese Beispiele zielen darauf ab, Ihre Ideen und Anregungen zur Verwendung der Ankerpositionierung zum Ausdruck zu bringen. Die beste Möglichkeit, die Spezifikation weiter auszubauen, ist das Feedback von echten Nutzenden wie Ihnen.

Kontextmenüs

Beginnen wir mit einem Kontextmenü unter Verwendung der Popover API. Die Idee dahinter ist, dass durch Klicken auf die Schaltfläche mit dem Chevron ein Kontextmenü angezeigt wird. Dieses Menü hat dann ein eigenes Menü, das maximiert werden kann.

Das Markup ist hier nicht der wichtige Teil. Sie haben aber drei Schaltflächen mit popovertarget. Dann haben Sie drei Elemente mit dem Attribut popover. Dadurch haben Sie die Möglichkeit, die Kontextmenüs ohne JavaScript zu öffnen. Das könnte so aussehen:

<button popovertarget="context">
  Toggle Menu
</button>        
<div popover="auto" id="context">
  <ul>
    <li><button>Save to your Liked Songs</button></li>
    <li>
      <button popovertarget="playlist">
        Add to Playlist
      </button>
    </li>
    <li>
      <button popovertarget="share">
        Share
      </button>
    </li>
  </ul>
</div>
<div popover="auto" id="share">...</div>
<div popover="auto" id="playlist">...</div>

Jetzt können Sie ein position-fallback definieren und zwischen den Kontextmenüs teilen. Die Festlegung aller inset-Stile für die Popovers muss ebenfalls aufgehoben werden.

[popovertarget="share"] {
  anchor-name: --share;
}

[popovertarget="playlist"] {
  anchor-name: --playlist;
}

[popovertarget="context"] {
  anchor-name: --context;
}

#share {
  anchor-default: --share;
  position-fallback: --aligned;
}

#playlist {
  anchor-default: --playlist;
  position-fallback: --aligned;
}

#context {
  anchor-default: --context;
  position-fallback: --flip;
}

@position-fallback --aligned {
  @try {
    top: anchor(top);
    left: anchor(right);
  }

  @try {
    top: anchor(bottom);
    left: anchor(right);
  }

  @try {
    top: anchor(top);
    right: anchor(left);
  }

  @try {
    bottom: anchor(bottom);
    left: anchor(right);
  }

  @try {
    right: anchor(left);
    bottom: anchor(bottom);
  }
}

@position-fallback --flip {
  @try {
    bottom: anchor(top);
    left: anchor(left);
  }

  @try {
    right: anchor(right);
    bottom: anchor(top);
  }

  @try {
    top: anchor(bottom);
    left: anchor(left);
  }

  @try {
    top: anchor(bottom);
    right: anchor(right);
  }
}

Dadurch erhalten Sie eine adaptive verschachtelte Kontextmenü-UI. Versuche, die Inhaltsposition über „Auswählen“ zu ändern. Die Option, mit der Sie die Rasterausrichtung aktualisieren. Dies beeinflusst, wie die Ankerpositionen die Pop-over positionieren.

Fokussieren und folgen

In dieser Demo werden CSS-Primitive kombiniert, indem :has() integriert wird. Die Idee ist, einen visuellen Indikator für input zu verwenden, der im Fokus steht.

Dazu legen Sie zur Laufzeit einen neuen Anker fest. In dieser Demo wird eine benutzerdefinierte Eigenschaft mit Umfang auf den Eingabefokus aktualisiert.

#email {
    anchor-name: --email;
  }
  #name {
    anchor-name: --name;
  }
  #password {
    anchor-name: --password;
  }
:root:has(#email:focus) {
    --active-anchor: --email;
  }
  :root:has(#name:focus) {
    --active-anchor: --name;
  }
  :root:has(#password:focus) {
    --active-anchor: --password;
  }

:root {
    --active-anchor: --name;
    --active-left: anchor(var(--active-anchor) right);
    --active-top: calc(
      anchor(var(--active-anchor) top) +
        (
          (
              anchor(var(--active-anchor) bottom) -
                anchor(var(--active-anchor) top)
            ) * 0.5
        )
    );
  }
.form-indicator {
    left: var(--active-left);
    top: var(--active-top);
    transition: all 0.2s;
}

Aber wie können Sie noch mehr tun? Sie könnten es für eine Art Lehr-Overlay verwenden. Eine Kurzinfo kann zwischen POIs wechseln und ihren Inhalt aktualisieren. Sie könnten den Inhalt überblenden. Diskrete Animationen zum Animieren von display oder Übergängen der Ansicht funktionieren hier.

Balkendiagramm berechnen

Eine weitere unterhaltsame Funktion zur Ankerpositionierung ist die Kombination mit calc. Stellen Sie sich ein Diagramm mit einigen Pop-overs vor, die das Diagramm kommentieren.

Sie können die höchsten und niedrigsten Werte mit den CSS-Funktionen min und max erfassen. Der entsprechende CSS-Code könnte etwa so aussehen:

.chart__tooltip--max {
    left: anchor(--chart right);
    bottom: max(
      anchor(--anchor-1 top),
      anchor(--anchor-2 top),
      anchor(--anchor-3 top)
    );
    translate: 0 50%;
  }

Es gibt JavaScript, um die Diagrammwerte zu aktualisieren, und CSS, um das Diagramm zu gestalten. Die Ankerpositionierung übernimmt jedoch die Aktualisierungen des Layouts.

Größe der Ziehpunkte anpassen

Sie müssen dabei nicht nur an einem Element verankern. Für ein Element können viele Anker verwendet werden. Vielleicht ist Ihnen das im Beispiel mit dem Balkendiagramm aufgefallen. Die Kurzinfos waren mit dem Diagramm und dem entsprechenden Balken verankert. Wenn Sie dieses Konzept noch weiter ausbauen, könnten Sie damit die Größe von Elementen anpassen.

Sie können die Ankerpunkte wie benutzerdefinierte Ziehpunkte zur Größenanpassung behandeln und einen inset-Wert festlegen.

.container {
   position: absolute;
   inset:
     anchor(--handle-1 top)
     anchor(--handle-2 right)
     anchor(--handle-2 bottom)
     anchor(--handle-1 left);
 }

In dieser Demo macht GreenSock ziehbar die Ziehpunkte ziehbar. Die Größe des <img>-Elements wird jedoch angepasst, um den Container zu füllen. Dieser wird dann angepasst, um die Lücke zwischen den Ziehpunkten zu füllen.

Ein SelectMenu?

Die letzte Frage ist ein Vorgeschmack auf das, was Sie erwartet. Sie können jedoch ein fokussierbares Pop-over erstellen und haben jetzt eine Ankerpositionierung. Sie können die Grundlagen eines anpassbaren <select>-Elements schaffen.

<div class="select-menu">
<button popovertarget="listbox">
 Select option
 <svg>...</svg>
</button>
<div popover="auto" id="listbox">
   <option>A</option>
   <option>Styled</option>
   <option>Select</option>
</div>
</div>

Ein implizites anchor erleichtert dies. Das CSS für einen rudimentären Ausgangspunkt könnte jedoch wie folgt aussehen:

[popovertarget] {
 anchor-name: --select-button;
}
[popover] {
  anchor-default: --select-button;
  top: anchor(bottom);
  width: anchor-size(width);
  left: anchor(left);
}

Wenn Sie die Funktionen der Popover API mit der Positionierung des CSS-Ankers kombinieren, sind Sie ganz nah dran.

Schön, wenn du beginnst, Dinge wie :has() vorzustellen. Sie können die Markierung beim Öffnen drehen:

.select-menu:has(:open) svg {
  rotate: 180deg;
}

Was könnten Sie als Nächstes tun? Was brauchen wir noch, damit select funktioniert? Das speichern wir für den nächsten Artikel. Aber keine Sorge, es kommen anpassbare Elemente zur Auswahl. Mehr dazu demnächst!


Geschafft!

Die Webplattform entwickelt sich weiter. Die Positionierung von CSS-Ankern spielt eine wichtige Rolle bei der Entwicklung von UI-Steuerelementen. Sie werden Sie von einigen dieser kniffligen Entscheidungen abstrahieren. Aber die App bietet Ihnen auch Möglichkeiten, Dinge zu tun, die Sie vorher noch nie hatten. z. B. die Gestaltung eines <select>-Elements. Wir würden gern Ihre Meinung zum Google Partners-Programm erfahren.

Foto von CHUTTERSNAP auf Unsplash